我希望返回类型基于“ config”参数
现在返回exampleFn函数的类型为空{}
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
在我看来很好。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句