![](/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.