簡體   English   中英

“pick”函數的 TypeScript 泛型類型(結果對象值類型)

[英]TypeScript generic type for "pick" function (result object values types)

有問題寫類型選擇功能。 僅選擇一個或多個具有相同類型值的鍵時,一切正常。 但是如果我試圖選擇幾個鍵並且它們的值是不同的類型 - 我會得到一個錯誤。 不太確定我在哪里犯了錯誤。

感謝您的時間。

export interface Mapper<T = any, R = any> {
  (arg: T): R;
}


export function pick<O, T extends keyof O>(keys: T[], obj?: O): { [K in T]: O[T] };

export function pick<T>(keys: T[], obj?: never): Mapper;

export function pick<O, T extends keyof O>(keys: T[], obj?: O) {
  const picker: Mapper<O, { [K in T]: O[T] }> = _obj =>
    keys.reduce((acc, key) => {
      if (key in _obj) {
        acc[key] = _obj[key];
      }
      return acc;
    }, {} as O);

  return obj ? picker(obj) : picker;
}

const obj = { someKey: 'value', otherKey: 42, moreKey: ['array value'] };

const newObj = pick(['otherKey'], obj);
//OK. TS type for newObj is {otherKey: number}

const n: number = newObj.otherKey;
// OK

const otherNewObj = pick(['otherKey', 'someKey'], obj);
//no really OK. TS type for otherNewObj is {otherKey: number | string, someKey: number | string}

const m: number = otherNewObj.someKey;
// Error. Type string | number is not assignable to the number

您的映射類型有錯誤,您可能想使用O[K]而不是O[T]因此最終得到{ [K in T]: O[K] } 您需要每個鍵K的類型,而不是T聯合中所有屬性的類型。

此外,我會使用Pick因為Pick是同態的並且會保留諸如readonlyoptional修飾符。

還有obj?: never可能不會做你想要它做的事情,任何東西都可以分配給never ,你最好省略那個重載中的參數:

export function pick<O, T extends keyof O>(keys: T[], obj?: O): Pick<O, T>;
export function pick<T>(keys: T[]): Mapper;
export function pick<O, T extends keyof O>(keys: T[], obj?: O) {
    //....
}

游樂場鏈接

暫無
暫無

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

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