#typescript #typescript-typings
#typescript #typescript-типизации
Вопрос:
Только что нашел следующий фрагмент кода в https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-differentiating-types
type FunctionPropertyNames<T> = {
[K in keyof T]: T[K] extends Function ? K : never;
}[keyof T];
type FunctionProperties<T> = Pick<T, FunctionPropertyNames<T>>;
что [keyof T]
означает объявление типа после и как оно называется?
Также [keyof T]
похоже на подсказку для компилятора, что ключи в FunctionalPropertyNames
являются ключами из T , но почему компилятор не может вывести это из [K in keyof T]
?
Ответ №1:
Краткое объяснение: при таком использовании получают все типы значений всех свойств.
Прежде всего, []
после того, как тип переходит к этому типу, обращаясь к этому типу с помощью ключа (или ключей)
type A = { foo: string }
type B = A['foo'] // string
Во-вторых, здесь у вас есть сопоставленный тип. Это означает, что это тип, который сопоставляет все ключи некоторого типа, преобразует его, а затем возвращает новый тип.
Итак, давайте сначала рассмотрим эту часть самостоятельно:
type StripNonMethods<T> = {
[K in keyof T]: T[K] extends Function ? K : never;
}
Что бы это ни T
было, это создаст тип, который для всех ключей T
которого значением каждого свойства является либо имя свойства (если значение является функцией), либо never
(если это не функция).
Это преобразовало бы это:
type T1 = { a(): void, b: number }
в:
type T2 = StripNonMethods<T1> // { a: 'a', b: never }
Но желаемым результатом здесь является строка 'a'
, потому что мы пытаемся получить все имена свойств, которые являются функциями. Итак, мы переходим к этому типу с его собственными ключами, который возвращает все значения всех свойств в виде объединения с [keyof T]
в конце.
Теперь это вернет:
type T3 = T2[keyof T2] // 'a' | never
И поскольку never
оно никогда не может существовать, по определению, оно упрощается из объединения, и вы просто получаете:
'a'
Ответ №2:
Синтаксис с квадратными скобками называется индексированными типами доступа. Используется для получения типа свойства определенного типа. Например:
Допустим, у нас есть тип с именем AlmostRectangle:
type AlmostRectangle = {
name: string;
a: number;
b: number;
start: Date;
};
Мы можем получить тип определенного свойства, используя синтаксис индексированных типов доступа:
type NameType = AlmostRectangle["name"]; // string
Мы можем передать объединение имен ключей в квадратные скобки, чтобы получить объединение типов свойств, например:
type MultipleTypes = AlmostRectangle["name" | "start"] // string | Date
keyof AlmostRectangle
возвращает объединение AlmostRectangle
имен свойств: "name" | "a" | "b" | "start"
. Мы можем использовать это, чтобы получить все типы
свойств AlmostRectangle:
type AlmostRectangleProperty = AlmostRectangle[keyof AlmostRectangle] // string | number | Date