簡體   English   中英

Typescript:如何根據參數類型獲取 function 的返回類型?

[英]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] };
};

您可以看到我斷言keykeyof Interface (因為編譯器只知道keystring )並且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

在我看來很好。

Playground 代碼鏈接

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM