如何推断 return 泛型函数的类型
How to infer return type of a generic function
我有一个函数总是 return 一个类型,虽然它可以改变并且手动定义它会有些工作并且不可扩展,所以我试图通过使用打字稿的 infer
关键词
起初我看到了this reddit post
使用
type Foo<T> = T extends { a: infer U, b: infer U } ? U : never;
type T10 = Foo<{ a: string, b: string }>; // string
type T11 = Foo<{ a: string, b: number }>; // string | number
问题是,我的类型是泛型函数
这是一个最小的例子,
const fnFromLib = <T>(a: string, b: Record<string, string>) => {
return function barFn(c: T) {
return {
c,
b: b[a],
};
};
};
const foo = <T>(a: Record<string, string>) => {
return {
bar: fnFromLib<T>('foo', a),
};
};
type returnTypeInferer<T> = T extends (a: Record<string, string>) => infer U ? U : never;
type fooType = typeof foo;
type fooReturnType = returnTypeInferer<fooType>;
没有错误,但是,由于没有传递通用类型,fooReturnType
将被推断为
type fooReturnType = {
bar: (c: unknown) => {
c: unknown;
b: string;
};
}
注意到 fnFromLib 中的 T 不是从参数推断出来的,应该在函数调用中传递 我尝试将类型参数从 fooReturnType
传递到 fooType
,但这给了我一个解析错误
type returnTypeInferer<T> = T extends (a: Record<string, string>) => infer U ? U : never;
type fooType<T> = typeof foo<T>; // ------ parsing error: ';' expected ---------
type fooReturnType<T> = returnTypeInferer<fooType<T>>;
有什么方法可以实现我想要的吗?
谢谢
设法通过将函数包装成通用函数来做到这一点 class
class GnClass<T> {
foo = (a: Record<string, string>) => {
return {
bar: fnFromLib<T>('foo', a),
};
};
}
type returnTypeInferer<T> = T extends (a: Record<string, string>) => infer U ? U : never;
type fooType<T> = GnClass<T>['foo'];
type fooReturnType<T> = returnTypeInferer<fooType<T>>;
但我想坚持使用函数式编程,我不会将此标记为已接受的答案,暂时使用它,因为目前我看不到其他选择并且会喜欢其他方法。
我有一个函数总是 return 一个类型,虽然它可以改变并且手动定义它会有些工作并且不可扩展,所以我试图通过使用打字稿的 infer
关键词
起初我看到了this reddit post 使用
type Foo<T> = T extends { a: infer U, b: infer U } ? U : never;
type T10 = Foo<{ a: string, b: string }>; // string
type T11 = Foo<{ a: string, b: number }>; // string | number
问题是,我的类型是泛型函数
这是一个最小的例子,
const fnFromLib = <T>(a: string, b: Record<string, string>) => {
return function barFn(c: T) {
return {
c,
b: b[a],
};
};
};
const foo = <T>(a: Record<string, string>) => {
return {
bar: fnFromLib<T>('foo', a),
};
};
type returnTypeInferer<T> = T extends (a: Record<string, string>) => infer U ? U : never;
type fooType = typeof foo;
type fooReturnType = returnTypeInferer<fooType>;
没有错误,但是,由于没有传递通用类型,fooReturnType
将被推断为
type fooReturnType = {
bar: (c: unknown) => {
c: unknown;
b: string;
};
}
注意到 fnFromLib 中的 T 不是从参数推断出来的,应该在函数调用中传递 我尝试将类型参数从 fooReturnType
传递到 fooType
,但这给了我一个解析错误
type returnTypeInferer<T> = T extends (a: Record<string, string>) => infer U ? U : never;
type fooType<T> = typeof foo<T>; // ------ parsing error: ';' expected ---------
type fooReturnType<T> = returnTypeInferer<fooType<T>>;
有什么方法可以实现我想要的吗?
谢谢
设法通过将函数包装成通用函数来做到这一点 class
class GnClass<T> {
foo = (a: Record<string, string>) => {
return {
bar: fnFromLib<T>('foo', a),
};
};
}
type returnTypeInferer<T> = T extends (a: Record<string, string>) => infer U ? U : never;
type fooType<T> = GnClass<T>['foo'];
type fooReturnType<T> = returnTypeInferer<fooType<T>>;
但我想坚持使用函数式编程,我不会将此标记为已接受的答案,暂时使用它,因为目前我看不到其他选择并且会喜欢其他方法。