![](/img/trans.png)
[英]How can I control the return type based on an argument in Typescript?
[英]Typescript: How can I get return type of function based on argument type?
我希望返回类型基于“config”参数
现在返回 exampleFn function 的类型为空 {}
interface Interface {
a: number;
b: string;
}
const DEFAULT_VALUES = {
a: (num: number) => 1 + num,
b: (str: string) => 'a' + str,
}
const exampleFn = <T extends Partial<Interface>>(config: T) => {
const map = {};
Object.entries(config).forEach(([key, val]) => {
map[key] = DEFAULT_VALUES[key];
});
return map;
};
const example1 = exampleFn({ a: 123 }); // I want example1 return type to be "{a: (num: number) => number}"
const example2 = exampleFn({ b: 'asd' }); // I want example2 return type to be "{b: (str: string) => string}"
const example3 = exampleFn({ a: 123, b: 'asd' }); // I want example3 return type to be "{a: (num: number) => number, b: (str: string)} => string"
可能吗?
编译器不会聪明到自己解决这个问题,但你当然可以描述你想要的类型并在exampleFn()
的实现中使用类型断言来防止它抱怨......记住这样的类型断言将类型安全的负担从编译器转移到您身上。
这是我认为你想要的类型:
{ [K in Extract<keyof T, keyof Interface>]: typeof DEFAULT_VALUES[K] }
基本上你正在制作一个映射类型,其中键是来自T
的键,它们也存在于Interface
中( T
可能包含更多键,因为T extends Partial<Interface>
允许这样的扩展;如果你真的想禁止这个,你可以,但是现在我将保留它),并且值是来自DEFAULT_VALUES
值的相应类型。
这是实现:
const exampleFn = <T extends Partial<Interface>>(config: T) => {
const map = {} as any;
Object.entries(config).forEach(([key, val]) => {
map[key] = DEFAULT_VALUES[key as keyof Interface];
});
return map as { [K in Extract<keyof T, keyof Interface>]: typeof DEFAULT_VALUES[K] };
};
您可以看到我断言key
是keyof Interface
(因为编译器只知道key
是string
)并且map
是所需的返回类型。 让我们看看它是如何工作的:
const example1 = exampleFn({ a: 123 });
console.log(example1.a(123)); // 124
console.log(example1.b); // undefined
// error! --------> ~
// Property 'b' does not exist on type '{ a: (num: number) => number; }'
const example2 = exampleFn({ b: 'asd' });
console.log(example2.b("asd")); // aasd
const example3 = exampleFn({ a: 123, b: 'asd' });
console.log(example3.b("asd")); // aasd
console.log(example3.a(123)); // 124
在我看来很好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.