我有以下工作代码:
interface Box {
length: number;
width: number;
height: number;
}
const box: Box = {
length: 2,
width: 1,
height: 3
};
type PickWithArray<T, A extends readonly (keyof T)[]> = Pick<T, A[number]>;
const keysArray = ["length", "width"] as const;
type Extracted = PickWithArray<Box, typeof keys2>;
这很好用,但是当我创建keysArray
时,我想将数组的值限制为该类型的键,以便可以在IDE中自动完成。我尝试了以下操作:
type PickWithArrayKeys<T> = Array<keyof T>;
const pickedKeys: PickWithArrayKeys<Box> = ["length", "width"];
const keysArray = [...pickedKeys] as const; // Doesn't work, original type is persisted
type Extracted = PickWithArray<Box, typeof keysArray>;
这不起作用,因为typeof keysArray
实际上是("length" | "width" | "height")[]
,所以Extracted
最终是:
type Extracted = {
length: number;
width: number;
height: number; <-- want this to be excluded
}
答案 0 :(得分:0)
我将引入一个辅助函数,将数组中的值约束为Box
的键的元素,而不仅产生Array<keyof Box>
:
const asKeysArray = <T>() => <K extends keyof T>(...k: K[]) => k;
const asBoxKeysArray = asKeysArray<Box>();
第一个asKeysArray()
函数采用类型T
并产生一个新函数,该函数仅接受T
类型的键。如果我们给它Box
,我们将得到asBoxKeysArray()
。然后可以这样调用此函数:
const keysArray = asBoxKeysArray("length", "width");
// const keysArray: ("length" | "width")[]
您会看到keysArray
的类型为Array<"length" | "width">
,足以使Extracted
成为您想要的类型:
type Extracted = PickWithArray<Box, typeof keysArray>;
/*
type Extracted = {
length: number;
width: number;
}
*/
在旁边:您可能想知道为什么没有单个函数function asKeysArray<T, K extends keyof T>(...k: K[]): K[];
。也就是说,为什么我要让一个通用函数接受T
并返回一个新的通用函数接受K
?答案是在TypeScript中目前无法执行partial type parameter inference(请参阅related question),因此,如果我们要指定T
但要推断出K
,则必须这样做此功能返回功能的东西或其他解决方法。
无论如何,这应该对您有用。希望能有所帮助;祝你好运!