Объявление типа Typescript в квадратных скобках

#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