如何从TypeScript类型对象中提取指定键生成新类型?
给定TypeScript类型:
type TestObj = { one: "up"; two: "down"; three: "left"; four: "right"; }
尝试从TestObj中选择部分键生成新类型:
type TestObjKeys = keyof TestObj; const chosen: TestObjKeys[] = ["one", "four"]; type NewTestObj = Pick<TestObj, (typeof chosen)[number]>;
此时NewTestObj会被推断为和TestObj完全一致的类型,而非仅包含one和four的类型。另外尝试用const chosen2 = chosen as const做常量断言时,会出现错误:
A 'const' assertions can only be applied to references to enum members, or string, number, boolean, array, or object literals.(1355)
请问如何实现仅提取所选键的新TypeScript类型?
问题根源在于chosen被声明为TestObjKeys[]类型后,TypeScript会将其推断为包含所有TestObj键的数组类型,而非仅包含"one"和"four"的字面量数组。以下是两种可行的解决方式:
方式一:直接对数组字面量使用const断言
跳过显式的TestObjKeys[]类型声明,直接给数组字面量添加as const,让TypeScript保留精确的字面量类型:
type TestObj = { one: "up"; two: "down"; three: "left"; four: "right"; } const chosen = ["one", "four"] as const; type NewTestObj = Pick<TestObj, typeof chosen[number]>; // NewTestObj 类型为 { one: "up"; four: "right"; }
这种方式下,chosen的类型会被锁定为只读的readonly ["one", "four"],typeof chosen[number]就是精确的"one" | "four",因此Pick能正确生成目标类型。
方式二:用泛型约束保留类型精度
如果需要保留chosen变量的可变性(比如后续可以修改数组内容,但仍限制为TestObj的键),可以通过泛型函数来约束类型并保留字面量信息:
type TestObj = { one: "up"; two: "down"; three: "left"; four: "right"; } function createChosenKeys<T extends keyof TestObj>(keys: T[]) { return keys; } const chosen = createChosenKeys(["one", "four"]); type NewTestObj = Pick<TestObj, typeof chosen[number]>; // NewTestObj 类型为 { one: "up"; four: "right"; }
泛型函数会根据传入的数组字面量推断出精确的T类型(即"one" | "four"),同时约束keys只能是TestObj的键组成的数组。如果后续修改chosen的元素,只要是TestObj的键,类型也会同步更新。
内容的提问来源于stack exchange,提问作者SILENT

