私は次の機能を持っています:
function test(): number {
return 42;
}
関数のタイプは、次を使用して取得できますtypeof
。
type t = typeof test;
ここでt
は、になります() => number
。
関数の戻り値の型を取得する方法はありますか?の代わりt
になりたいnumber
です() => number
。
私は次の機能を持っています:
function test(): number {
return 42;
}
関数のタイプは、次を使用して取得できますtypeof
。
type t = typeof test;
ここでt
は、になります() => number
。
関数の戻り値の型を取得する方法はありますか?の代わりt
になりたいnumber
です() => number
。
回答:
編集
TypeScript 2.8以降、これは公式に可能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[]
詳細はこちらをご覧ください。
TypeScriptは素晴らしいです!
昔ながらのハック
残念ながら、ライアンの答えはもう機能しません。しかし、私はそれを私が不当に満足しているハックで修正しました。見よ:
const fnReturnType = (false as true) && fn();
これは、falseをリテラル値trueにキャストすることで機能するため、型システムは戻り値が関数の型であると見なしますが、実際にコードを実行すると、falseで短絡します。
TypeScriptが最適です。:D
Cannot find name 'ReturnType'
ます。vscodeの使用
ReturnType<typeof fn>
(答えReturnType<fn>
は十分であることを意味します)。
以下のコードは、関数を実行しなくても機能します。これは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;
これを行う方法はありません(これを追加する作業項目の追跡については、https://github.com/Microsoft/TypeScript/issues/6606を参照してください)。
一般的な回避策は、次のようなものを書くことです。
var dummy = false && test();
type t2 = typeof dummy;
編集:これはTS 2.8ではもう必要ありません!ReturnType<F>
戻り値の型を示します。受け入れられた答えを参照してください。
私が使用している以前の回答のいくつかの変形でstrictNullChecks
あり、推論体操で機能し、少し隠します。
function getReturnType<R>(fn: (...args: any[]) => R): R {
return {} as R;
}
使用法:
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; }
それはない呼び出すgetReturnType
関数が、それはしない元の関数を呼び出します。あなたはgetReturnType
を使用して通話を防ぐことができます(false as true) && getReturnType(foo)
、IMOすると、混乱が増します。
このメソッドを正規表現の検索/置換とともに使用して、元々JSでこのように記述された約1500のファクトリ関数を持つ古いAngular 1.xプロジェクトを移行し、Foo
すべての用途にetcタイプを追加しました...壊れたコード1つ見つけます。:)
ReturnType<F>
、関数の戻り値の型を取得するために使用できます。:)
test
。この答えは、名前test
を変更するだけの場合foo
(そして、キックの場合は、より複雑な戻り値の型を生成するため)に役立つものの1つでした。元の例にそれらを適用する方法をすでに知っている場合は、受け入れられた回答とコメントの両方がおそらく素晴らしいでしょう。(ここでは深夜であり、完全なReturnTypeの例の構文がどのようになるかはすぐにはわかりません。)
問題の関数がユーザー定義クラスのメソッドである場合、Reflectメタデータと組み合わせてメソッドデコレータを使用して、実行時に戻り値の型(コンストラクタ関数)を決定できます(そして、それを使用して、必要に応じて実行します)。
たとえば、コンソールにログを記録できます。
function logReturnType(
target: Object | Function,
key: string,
descriptor: PropertyDescriptor
): PropertyDescriptor | void {
var returnType = Reflect.getMetadata("design:returntype", target, key);
console.log(returnType);
}
このメソッドデコレータを選択したメソッドにスナップするだけで、メソッド呼び出しから返されると思われるオブジェクトのコンストラクタ関数への正確な参照が得られます。
class TestClass {
@logReturnType // logs Number (a string representation)
public test(): number {
return 42;
}
}
ただし、このアプローチにはいくつかの注目すべき制限があります。
Reflect.getMetadata
、から未定義になります。また、デコレータとリフレクトメタデータはどちらもこの投稿の執筆時点では実験的な機能であるため、typescriptコンパイラには次のコマンドライン引数を指定する必要があります。
--emitDecoratorMetadata --experimentalDecorators
悲しいことに実行せずに関数の戻り値の型を取得する方法はありません。これは、TypeScriptがJSにコンパイルされると、タイプに関するすべての情報が失われるためです。
ReturnType<T>
、TypeScriptに実装されたことでさらに明白になりました。
私は次のことを思いつきました。これはうまく機能しているようです。
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
fn: (...args: any[]) => Z
は、あなたが必要とすることすべてです。