Я хочу написать функцию, которая делает три вещи:
- работает с универсальным типом T
- принимает ключ: K из T, где T[K] должен быть логическим значением
- присваивает значение T[K]
Я следую этому руководству, которое подсказывает при такой возможности:
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 не позволяет мне работать с дженериками таким образом и что я могу сделать, чтобы это исправить?