Tengo la siguiente función:
function test(): number {
return 42;
}
Puedo obtener el tipo de función usando typeof
:
type t = typeof test;
Aquí t
estará () => number
.
¿Hay alguna forma de obtener el tipo de retorno de la función? Me gustaría t
ser en number
lugar de () => number
.
typescript
typescript1.8
eliminar
fuente
fuente
Respuestas:
EDITAR
A partir de TypeScript 2.8, esto es oficialmente posible con
ReturnType<T>
.type T10 = ReturnType<() => string>; // string type T11 = ReturnType<(s: string) => void>; // void type T12 = ReturnType<(<T>() => T)>; // {} type T13 = ReturnType<(<T extends U, U extends number[]>() => T)>; // number[]
Consulte aquí para obtener más detalles.
¡TypeScript es increíble!
Hack de la vieja escuela
La respuesta de Ryan ya no funciona, desafortunadamente. Pero lo modifiqué con un truco que me alegra irrazonablemente. Mirad:
const fnReturnType = (false as true) && fn();
Funciona al convertir falso al valor literal de verdadero, de modo que el sistema de tipos piensa que el valor de retorno es el tipo de la función, pero cuando realmente ejecuta el código, se cortocircuita en falso.
TypeScript es el mejor. :RE
fuente
Cannot find name 'ReturnType'
:? usando vscodeReturnType<typeof fn>
(la respuesta implica queReturnType<fn>
es suficiente).La forma más sencilla en TypeScript 2.8:
const foo = (): FooReturnType => { } type returnType = ReturnType<typeof foo>; // returnType = FooReturnType
fuente
El siguiente código funciona sin ejecutar la función. Es de la biblioteca react-redux-typescript ( https://github.com/alexzywiak/react-redux-typescript/blob/master/utils/redux/typeUtils.ts )
interface Func<T> { ([...args]: any, args2?: any): T; } export function returnType<T>(func: Func<T>) { return {} as T; } function mapDispatchToProps(dispatch: RootDispatch, props:OwnProps) { return { onFinished() { dispatch(action(props.id)); } } } const dispatchGeneric = returnType(mapDispatchToProps); type DispatchProps = typeof dispatchGeneric;
fuente
No hay una manera de hacer esto (consulte https://github.com/Microsoft/TypeScript/issues/6606 para el seguimiento del elemento de trabajo que agrega esto).
Una solución alternativa común es escribir algo como:
var dummy = false && test(); type t2 = typeof dummy;
fuente
!1
lugar defalse
- typescriptlang.org/play/…Editar: ¡ Esto ya no es necesario con TS 2.8!
ReturnType<F>
da el tipo de retorno. Ver respuesta aceptada.Una variante de algunas de las respuestas anteriores que estoy usando, que funciona
strictNullChecks
y oculta un poco la gimnasia de inferencia:function getReturnType<R>(fn: (...args: any[]) => R): R { return {} as R; }
Uso:
function foo() { return { name: "", bar(s: string) { // doesn't have to be shorthand, could be `bar: barFn` return 123; } } } const _fooReturnType = getReturnType(foo); export type Foo = typeof _fooReturnType; // type Foo = { name: string; bar(s: string): number; }
Se hace llamar a la
getReturnType
función, pero no llama a la función original. Usted podría evitar que lagetReturnType
llamada usando(false as true) && getReturnType(foo)
pero En mi opinión esto sólo lo hace más confuso.Acabo de usar este método con un poco de búsqueda / reemplazo de expresiones regulares para migrar un antiguo proyecto Angular 1.x que tenía ~ 1500 funciones de fábrica escritas así, originalmente en JS, y agregué los
Foo
tipos, etc. a todos los usos ... asombroso el código roto uno encontrará. :)fuente
ReturnType<F>
para obtener un tipo de retorno de funciones. :)test
. Esta respuesta fue una de las más útiles para solo cambiar el nombretest
afoo
(y, ciertamente, producir un tipo de retorno más complejo, por diversión). Tanto la respuesta aceptada como su comentario probablemente sean excelentes si ya sabe cómo aplicarlos al ejemplo original. (Es tarde en la noche aquí, y no me parece inmediatamente evidente cómo se vería la sintaxis de un ejemplo completo de ReturnType.)Si la función en cuestión es un método de una clase definida por el usuario, puede usar decoradores de métodos junto con Reflect Metadata para determinar el tipo de retorno (función constructora) en tiempo de ejecución (y con él, hacer lo que crea conveniente).
Por ejemplo, puede registrarlo en la consola:
function logReturnType( target: Object | Function, key: string, descriptor: PropertyDescriptor ): PropertyDescriptor | void { var returnType = Reflect.getMetadata("design:returntype", target, key); console.log(returnType); }
Simplemente coloque este decorador de métodos en un método de su elección y tendrá la referencia exacta a la función constructora del objeto que supuestamente se devuelve desde la llamada al método.
class TestClass { @logReturnType // logs Number (a string representation) public test(): number { return 42; } }
Sin embargo, existen algunas limitaciones notables para este enfoque:
Reflect.getMetadata
,Además, deberá especificar los siguientes argumentos de línea de comando para el compilador de mecanografiado, porque tanto los decoradores como los metadatos reflect son características experimentales al momento de escribir esta publicación:
fuente
No hay forma de recuperar el tipo de retorno de la función sin ejecutarlo lamentablemente. Esto se debe a que cuando TypeScript se compila en JS, pierde toda la información sobre el tipo.
fuente
ReturnType<T>
se ha implementado en TypeScript.Se me ocurrió lo siguiente, que parece funcionar muy bien:
function returnType<A, B, Z>(fn: (a: A, b: B) => Z): Z function returnType<A, Z>(fn: (a: A) => Z): Z function returnType<Z>(fn: () => Z): Z function returnType(): any { throw "Nooooo" } function complicated(value: number): { kind: 'complicated', value: number } { return { kind: 'complicated', value: value } } const dummy = (false as true) && returnType(complicated) type Z = typeof dummy
fuente
fn: (...args: any[]) => Z
es todo lo que necesitas.