簡體   English   中英

Typescript - 返回 object 與參數 object 相同的鍵

[英]Typescript - Return object with same keys as argument object

返回 object 只需要具有參數 object 具有的鍵,並且鍵必須是字符串。

這是我到目前為止所擁有的:

type ArgumentObject<Key extends string> = Record<Key, string>;

type ResultObject<Key extends string> = Record<Key, boolean>;

function someFunction<Key extends string>(arg: ArgumentObject<Key>) {

  const result: ResultObject<keyof typeof arg> = {} as ResultObject<Key>;

  for (const k in Object.keys(arg)) {
    result[k as Key] = true;
  }

  return result;
}

僅當參數 object 的鍵是字符串時,Typescript 才能正確推斷結果 object 的形狀。 但您也可以將numbersymbol作為參數 object 中的鍵。

const result = someFunction({
  a: "abc",
  b: "def",
  1: "number allowed as key",
  [Symbol("a")]: "symbol also"
})

result.a // intellisense doesn't work

/////////////////////////////////////

const result = someFunction({
  a: "abc",
  b: "def"
})

result.a // intellisense works

此外,不必使用as進行所有類型轉換也很棒。

首先,可能存在一個誤解:當您在定義 object 文字時提供數字索引作為屬性時,它會被強制轉換為string 所以在你的例子中, 1是一個字符串,而不是一個數字:

{
  a: "abc",
  b: "def",
  1: "number allowed as key",
  [Symbol("a")]: "symbol also"
}

TypeScript 是結構類型的,所以只要一個類型可以extend (成為)所需類型的子類型,編譯器就會允許它。 在您的情況下, object 通過了具有字符串值的字符串鍵的要求(它也恰好有一個符號鍵)。

處理此問題的一種方法是使用條件返回類型,在有效分支中,它是映射類型 因此,雖然您仍然可以傳入具有不良屬性的對象,但如果這樣做,您將無法使用返回值。

TS游樂場

function someFunction <T extends Record<PropertyKey, string>>(arg: T): symbol extends keyof T ? never : number extends keyof T ? never : {
  [K in keyof T]: boolean;
} {
  const result = {} as any;
  for (const k in Object.keys(arg)) result[k as keyof T] = true;
  return result;
}

const result1 = someFunction({
  a: "abc",
  b: "def",
  1: "number allowed as key",
  [Symbol("a")]: "symbol also",
});

result1; // never
result1.a; /*
        ^
Property 'a' does not exist on type 'never'.(2339) */

const result2 = someFunction({
  a: 42, /*
  ^
Type 'number' is not assignable to type 'string'.(2322) */
  b: "def"
});

result2; // never
result2.a; /*
        ^
Property 'a' does not exist on type 'never'.(2339) */

const result3 = someFunction({
  a: "abc",
  b: "def"
});

result3; // { a: boolean; b: boolean; }
result3.a; // boolean

暫無
暫無

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

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