[英]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 的形狀。 但您也可以將number
和symbol
作為參數 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 通過了具有字符串值的字符串鍵的要求(它也恰好有一個符號鍵)。
處理此問題的一種方法是使用條件返回類型,在有效分支中,它是映射類型。 因此,雖然您仍然可以傳入具有不良屬性的對象,但如果這樣做,您將無法使用返回值。
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.