簡體   English   中英

根據 TypeScript 中的參數在字典中定義 function 的返回類型

[英]Define return type of a function in dictionary based on its parameter in TypeScript

我有一個 function 應該根據 function 參數返回不同的對象。 有沒有辦法在 Typescript 中實現這一點?

這是我已經走了多遠:

type returnMap = {
    'a': number,
    'b': string[]
}

function func<T extends returnMap, K extends keyof T>(val: K): T[K] {
    if (val == 'a') {return 5}
    if (val == 'b') {return ['a', 'b']}
    return 42
}
console.log(func('a'))  // 5

但是,它在返回值處顯示“TS2322:類型 '5' 不可分配給類型 'T[K]'”。

先感謝您

這將做:

interface ReturnMap {
  'a': number;
  'b': string[];
}

function func<K extends keyof ReturnMap>(val: K): ReturnMap[K];
function func(val: keyof ReturnMap): ReturnMap[keyof ReturnMap] {
  if (val === 'a') return 5;
  if (val === 'b') return ['a', 'b'];
  throw new Error();
}

const r1 = func('a'); // const r1: number
const r2 = func('b'); // const r2: string[]

// Argument of type '"c"' is not assignable to parameter of type '"a" | "b"'.ts(2345)
const r3 = func('c'); // const r3: number | string[]

注意 function 重載語法:

function func<K extends keyof ReturnMap>(val: K): ReturnMap[K];
function func(val: keyof ReturnMap): ReturnMap[keyof ReturnMap] { // ...

如果您只使用第二個簽名,則返回的類型將始終number | string[] number | string[]

如果您僅使用第一個簽名,則ReturnMap[K]被評估(在函數體內)為number & string[] ,這是逆變的,因此您會得到您在上面的問題中描述的錯誤。

或者,如果您不想使用重載簽名 - 您可以將結果投射到函數體內:

function func<K extends keyof ReturnMap>(val: K): ReturnMap[K] {
  if (val === 'a') return 5 as ReturnMap[K];
  if (val === 'b') return ['a', 'b'] as ReturnMap[K];
  throw new Error();
}

我認為重載可能會對您有所幫助:

type returnMap = {
    'a': number,
    'b': string[],
    'x': 42,
    'z': 42,
}

function func<T extends returnMap, K extends Exclude<keyof returnMap,'a'|'b'>>(val: K): 42;
function func<T extends returnMap, K extends 'b'>(val: K): string[];
function func<T extends returnMap, K extends 'a'>(val: K): number;
function func<T extends returnMap, K extends keyof T>(val: K): number | string[] {
    if (val == 'a') {
        return 5
    }
    if (val == 'b') {
        return ['a', 'b']
    }
    return 42
}

const result = func('a') // number
const result1 = func('b') // string[]
const result2 = func('x') // 42
const result3 = func('z') // 42

對於使用any作為返回變量的類型,這似乎是一個很好的用例。

請參閱https://www.typescriptlang.org/docs/handbook/basic-types.html#any

暫無
暫無

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

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