#typescript
#typescript
Вопрос:
Pick
Тип включен в TypeScript. Его реализация заключается в следующем:
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
Как бы вы написали PickByValue
тип, чтобы работало следующее:
type Test = {
includeMe: 'a' as 'a',
andMe: 'a' as 'a',
butNotMe: 'b' as 'b',
orMe: 'b' as 'b'
};
type IncludedKeys = keyof PickByValue<Test, 'a'>;
// IncludedKeys = 'includeMe' | 'andMe'
Комментарии:
1. Вы хотите, чтобы
PickByValue<Test, 'a' | 'b'>
это было эквивалентноTest
или эквивалентно{}
?
Ответ №1:
Предполагая, что вы намереваетесь Test
быть таким:
type Test = {
includeMe: 'a',
andMe: 'a',
butNotMe: 'b',
orMe: 'b'
};
и предполагая, что вы хотите PickByValue<T, V>
предоставить все свойства, которые являются подтипами V
(так что PickByValue<T, unknown>
должно быть T
), тогда вы можете определить PickByValue
следующим образом:
type PickByValue<T, V> = Pick<T, { [K in keyof T]: T[K] extends V ? K : never }[keyof T]>
type TestA = PickByValue<Test, 'a'>; // {includeMe: "a"; andMe: "a"}
type IncludedKeys = keyof PickByValue<Test, 'a'>; // "includeMe" | "andMe"
Но если все, что вам нужно, это IncludedKeys
, то вы можете сделать это более непосредственно с помощью KeysMatching<T, V>
:
type KeysMatching<T, V> = {[K in keyof T]: T[K] extends V ? K : never}[keyof T];
type IncludedKeysDirect = KeysMatching<Test, 'a'> // "includeMe" | "andMe"
Комментарии:
1. Поразмыслив над этим, я понял,
KeysMatching
что это немного более гибко для моего конкретного варианта использования. Я приблизился к своим первоначальным попыткам, но не совсем добился успеха. Большое спасибо!2. очень хороший ответ,
type IntermediateType { includeMe: includeMe", andMe: "andMe, butNotMe: never, orMe: never }
которыйtype Result = IntermediateType[string]
выдает"includeMe" | "andMe" | never | never
, ноnever
удален, поэтому это приводит к"includeMe" | "andMe"