【发布时间】:2020-01-31 13:37:23
【问题描述】:
我想写一个做三件事的函数:
- 对泛型类型 T 进行操作
- 接受一个键:K of T 其中 T[K] 必须是布尔值
- 为 T[K] 赋值
我正在关注this guide,这暗示了这种可能性:
type FunctionPropertyNames<T> = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T];
type FunctionProperties<T> = Pick<T, FunctionPropertyNames<T>>;
type NonFunctionPropertyNames<T> = { [K in keyof T]: T[K] extends Function ? never : K }[keyof T];
type NonFunctionProperties<T> = Pick<T, NonFunctionPropertyNames<T>>;
interface Part {
id: number;
name: string;
subparts: Part[];
updatePart(newName: string): void;
}
type T40 = FunctionPropertyNames<Part>; // "updatePart"
type T41 = NonFunctionPropertyNames<Part>; // "id" | "name" | "subparts"
type T42 = FunctionProperties<Part>; // { updatePart(newName: string): void }
type T43 = NonFunctionProperties<Part>; // { id: number, name: string, subparts: Part[] }
但是,如果我的函数在具体类型上运行,我似乎只能实现我的目标。为了计算 T 的布尔属性名称,我修改了示例中的第一行,如下所示:
type BoolPropNames<T> = { [K in keyof T]: T[K] extends boolean ? K : never }[keyof T];
如果我使用具体类型,它会起作用:
class Thing {
isGreat: boolean;
}
function assignToThing(thing: Thing, key: BoolPropNames<Thing>) {
thing[key] = false;
}
但如果我尝试对泛型进行操作,它不会:
function assign<T>(thing: T, key: BoolPropNames<T>) {
thing[key] = false;
}
当我尝试这样做时,TypeScript 给了我以下错误:
(parameter) key: { [K in keyof T]: T[K] extends boolean ? K : never; }[keyof T]
Type 'false' is not assignable to type 'T[{ [K in keyof T]: T[K] extends boolean ? K : never; }[keyof T]]'.ts(2322)
为什么 TypeScript 不允许我以这种方式对泛型进行操作,我可以做些什么来解决它?
【问题讨论】:
标签: typescript generics conditional-types