Generic fonksiyonun Typescript ReturnType'i
TypeScript 2.8'deki yeni ReturnType, belirli bir fonksiyonun dönüş türünü çıkarmanızı sağlayan gerçekten kullanışlı bir özelliktir.
function foo(e: number): number {
return e;
}
type fooReturn = ReturnType<typeof foo>; // number
Ancak, onu genel fonksiyonlar bağlamında kullanmakta zorlanıyorum.
function foo<T>(e: T): T {
return e;
}
type fooReturn = ReturnType<typeof foo>; // type fooReturn = {}
type fooReturn = ReturnType<typeof foo<number>>; // syntax error
type fooReturn = ReturnType<(typeof foo)<number>>; // syntax error
Belirli tür parametreleri verildiğinde bir generik fonksiyonun sahip olacağı dönüş türünü çıkarmanın bir yolu var mı?
Cevap #1
Bu daha önce tamamen genel bir şekilde yapmak imkansızdı, ancak Typescript 4.7'de mümkün olacak. Bu desen "Örnekleme İfadesi" olarak adlandırılıyor. İlgili PR burada. Açıklamadan alıntı:
function makeBox<T>(value: T) { return { value }; }; const makeStringBox = makeBox<string>; // (value: string) => { value: string } const stringBox = makeStringBox('abc'); // { value: string } const ErrorMap = Map<string, Error>; // new () => Map<string, Error> const errorMap = new ErrorMap(); // Map<string, Error> ```...
Özellikle kullanışlı bir desen, tip örnekleme ifadelerinde tip parametrelerine başvuran
typeofuygulamaları için genel tip takma adları oluşturmaktır:type BoxFunc<T> = typeof makeBox<T>; // (value: T) => { value: T } type Box<T> = ReturnType<typeof makeBox<T>>; // { value: T } type StringBox = Box<string>; // { value: string }
Cevap #2
Bu, içe aktarılan kütüphanelerin (örneğin knex gibi) dışa aktarılmamış dahili türlerini çıkarmak için şu anda çalışan çözümüm:
// foo is an imported function that I have no control over
function foo<T>(e: T): InternalType<T> {
return e;
}
class Wrapper<T> {
// wrapped has no explicit return type so we can infer it
wrapped(e: T) {
return foo<T>(e)
}
}
type FooInternalType<T> = ReturnType<Wrapper<T>['wrapped']>
type Y = FooInternalType<number>
// Y === InternalType<number>
Cevap #3
Eğer bazı özel genel türleri almak istiyorsanız, onu sarmalamak için sahte bir fonksiyon kullanabilirsiniz.
const wrapperFoo = () => foo<number>()
type Return = ReturnType<typeof wrapperFoo>
Daha karmaşık demo
function getList<T>(): {
list: T[],
add: (v: T) => void,
remove: (v: T) => void,
// ...blahblah
}
const wrapperGetList = () => getList<number>()
type List = ReturnType<typeof wrapperGetList>
// List = {list: number[], add: (v: number) => void, remove: (v: number) => void, ...blahblah}
