Saya memiliki fungsi berikut:
function test(): number {
return 42;
}
Saya bisa mendapatkan jenis fungsinya dengan menggunakan typeof
:
type t = typeof test;
Di sini, t
akan () => number
.
Apakah ada cara untuk mendapatkan tipe kembalian dari fungsi tersebut? Saya ingin t
menjadi number
gantinya () => number
.
typescript
typescript1.8
membersihkan
sumber
sumber
Jawaban:
EDIT
Pada TypeScript 2.8, ini secara resmi dimungkinkan dengan
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[]
Lihat permintaan tarik ini ke Microsoft / TypeScript untuk detailnya.
TypeScript luar biasa!
Retas sekolah tua
Sayangnya, jawaban Ryan tidak berfungsi lagi. Tapi saya telah memodifikasinya dengan peretasan yang membuat saya sangat senang. Melihat:
const fnReturnType = (false as true) && fn();
Ia bekerja dengan mentransmisikan
false
ke nilai literaltrue
, sehingga sistem tipe mengira nilai yang dikembalikan adalah jenis fungsinya, tetapi ketika Anda benar-benar menjalankan kode, itu korsletingfalse
.sumber
Cannot find name 'ReturnType'
? menggunakan vscodeReturnType<typeof fn>
(jawabannyaReturnType<fn>
sudah cukup).Cara termudah di TypeScript 2.8:
const foo = (): FooReturnType => { } type returnType = ReturnType<typeof foo>; // returnType = FooReturnType
sumber
Kode di bawah ini berfungsi tanpa menjalankan fungsi. Ini dari perpustakaan 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;
sumber
Tidak ada cara untuk melakukan ini (lihat https://github.com/Microsoft/TypeScript/issues/6606 untuk pelacakan item pekerjaan yang menambahkan ini).
Solusi umum adalah menulis sesuatu seperti:
var dummy = false && test(); type t2 = typeof dummy;
sumber
!1
alih - alihfalse
- typescriptlang.org/play/…Sunting: Ini tidak diperlukan lagi dengan TS 2.8!
ReturnType<F>
memberikan tipe pengembalian. Lihat jawaban yang diterima.Varian pada beberapa jawaban sebelumnya yang saya gunakan, yang berfungsi
strictNullChecks
dan menyembunyikan sedikit senam inferensi:function getReturnType<R>(fn: (...args: any[]) => R): R { return {} as R; }
Pemakaian:
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; }
Itu memang memanggil
getReturnType
fungsi, tapi tidak memanggil fungsi aslinya. Anda dapat mencegahgetReturnType
panggilan menggunakan(false as true) && getReturnType(foo)
tetapi IMO ini hanya membuatnya lebih membingungkan.Saya baru saja menggunakan metode ini dengan beberapa regexp find / replace untuk memigrasi proyek Angular 1.x lama yang memiliki ~ 1500 fungsi pabrik yang ditulis seperti ini, awalnya di JS, dan menambahkan
Foo
jenis dll ke semua penggunaan ... menakjubkan kode yang rusak satu akan menemukan. :)sumber
ReturnType<F>
untuk mendapatkan tipe pengembalian fungsi. :)test
. Jawaban ini adalah salah satu yang lebih berguna untuk hanya mengganti namatest
menjadifoo
(dan diakui menghasilkan jenis pengembalian yang lebih kompleks, untuk iseng). Jawaban yang diterima dan komentar Anda mungkin bagus jika Anda sudah tahu bagaimana menerapkannya pada contoh aslinya. (Ini sudah larut malam di sini, dan tidak langsung jelas bagi saya seperti apa sintaks dari contoh ReturnType lengkap akan terlihat.)Jika fungsi tersebut adalah metode kelas yang ditetapkan pengguna, Anda dapat menggunakan metode dekorator dalam conjuction dengan Reflect Metadata untuk menentukan jenis kembali (konstruktor) di runtime (dan dengan itu, lakukan sesuai keinginan Anda).
Misalnya, Anda dapat memasukkannya ke konsol:
function logReturnType( target: Object | Function, key: string, descriptor: PropertyDescriptor ): PropertyDescriptor | void { var returnType = Reflect.getMetadata("design:returntype", target, key); console.log(returnType); }
Cukup pasang dekorator metode ini pada metode pilihan Anda dan Anda memiliki referensi yang tepat ke fungsi konstruktor dari objek yang seharusnya dikembalikan dari pemanggilan metode.
class TestClass { @logReturnType // logs Number (a string representation) public test(): number { return 42; } }
Namun, ada beberapa batasan penting untuk pendekatan ini:
Reflect.getMetadata
,Selain itu, Anda harus menentukan argumen baris perintah berikut untuk compiler skrip ketikan, karena dekorator dan metadata mencerminkan adalah fitur eksperimental saat menulis posting ini:
sumber
Saya datang dengan yang berikut, yang tampaknya berfungsi dengan baik:
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
sumber
fn: (...args: any[]) => Z
adalah semua yang Anda butuhkan.