предисловие
Недавно, когда я писал React для определения типов переменных, я случайно нажал на ElementType, а затем нашел этот код в node_modules/@types/react/index.d.ts:
Ниу, хотя я не очень хорошо это понимаю, но я просто думаю, что это довольно круто.
поищи в Гугле
Но потом мы погуглили и обнаружили, что в Интернете это называется фильтрацией типов, что является практичным методом написания ТП.
Взгляните на это 🌰:
interface Example{
a:string;
b:number;
c:number;
d:string;
...
}
У нас есть интерфейс Example, но теперь мы хотим что-то сделать с этим интерфейсом и хотим оставить только свойства типа string, так что же нам делать? Вы можете использовать наш собственный определенный FilterType.
type newExample = FilterType<Example,string> // {a:string;d:string;...}
Давайте посмотрим, как реализован FilterType:
type FilterType<Source, Types> = Pick<
Source,
{
[K in keyof Source]: Source[K] extends Types ? K : never
}[keyof Source]
>;
анализировать
Во-первых, давайте взглянем на несколько типов утилит, которые появляются в коде. (Большой парень сразу пропускает)
in
in может перемещаться по типам перечисления, аналогично for...in
type Example = 'a' | 'b' | 'c' | 'd'
type Obj = {
[T in Example]: string; // 遍历Example,把每个key都赋值string类型
}
/* 等价于
type Obj = {
a: string;
b: string;
c: string;
d: string;
}
*/
keyof
В официальной документации TS он называетсяОператоры запроса типа индекса, вообще-то взять тип ключа, аналогичный Object.keys() хотя верной аналогии не знаю.
interface Example {
a: string;
b: string;
c: number;
d: boolean;
}
type Keys = keyof Example // 等价于 type Keys = 'a' | 'b' | 'c' | 'd'
Условное суждение
interface A {
a:string;
}
interface B extends A {
b:string;
}
// B是否继承于A?若是,则为number类型;若不是,则为string类型
type C = B extends A ? number : string // 等价于 type C = number
начать препарировать
Сначала взгляните на одну 🌰, приоткройте ее вуаль, нет, это маска:
type Mask<source,types> = {
[K in keyof source]:source[K] extends types ? K : never;
}
interface Example{
name:string;
height:number
}
type newType = Mask<Example,string> // { name:'name'; height:never}
В это время мы видим { name:'name'; height:never} , что??? Какая польза от этого?
Не волнуйтесь! Далее давайте продолжим смотреть на следующий пример, раскрывающий ее пальто:
Давайте взглянем на небольшой пункт знаний, который можно записать в блокнот:свойства интерфейса индексированного доступа
type person = {
name:"Angus";
height:185;
}["name" | "height"]
Эквивалентно:
type person = "Angus" | 185
Обратите внимание, что когда значение никогда не будет доступно
type person = {
name:"Angus";
height:185;
girlFriend:never;
}["name" | "height" | "girlFriend"]
Эквивалентно
type person = "Angus" | 185
(самоуничижительный
Так какой же смысл знать свойства интерфейса доступа к индексу? Посмотрите этот 🌰, чтобы показать ее одежду:
type Clothes<source,types> = {
[K in keyof source]:source[K] extends types ? K : never;
}[keyof source]
interface Example{
name:string;
height:number;
home:string
}
type newType = Clothes<Example,string> // type newType = "name | home"
Таким образом, мы можем получить тип объединения нужного нам типа.
Последний шаг, давайте раскрыть ***
Подожди, давайте сначала посмотрим на Пик.
Выбор — это выбор нескольких типов в объекте типа для формирования нового типа.
interface Angus{
name:string;
height:number;
wight:number;
}
type newAngus = Pick<Angus,'name' | 'height'> //{name:string;height:number}
Его реализация:
type Pick<T,K extends keyof T> = {
[P in K] : T[P];
}
Затем смотрим на тот, что есть в Google 🌰:
type FilterType<Source, Types> = Pick<
Source,
{
[K in keyof Source]: Source[K] extends Types ? K : never
}[keyof Source]
>;
Туалет открыт! ! ! Через Pick мы можем выбрать нужные нам атрибуты.
{
[K in keyof Source]: Source[K] extends Types ? K : never
}[keyof Source]
Эти две строки кода получат нужные нам свойства. Просто передайте Pick еще раз, и все готово. Это было показано?
расширять
Тогда давайте взглянем на некоторые другие типы инструментов в TS.
Omit
Omit(a,b) принимает два аргумента: первый — это базовый тип, который вы хотите изменить, а второй — это тип, который вы хотите удалить.
type Person = {
name:string;
sex:string;
}
type newPerson = Omit<Person,'name'> // {sex:string}
Посмотри, как это работает:
type Omit <T,K extends keyof any> = Pick<T,Exclude<keyof T,K>>;
Partial
Частичный может быстро превратить атрибуты, определенные в типе интерфейса, в необязательные (необязательные)
type Person = {
name:string;
sex:string;
}
type newPerson = Partial<Person> // {name?:string;sex?:string}
Посмотри, как это работает:
type Partial <T> = {
[P in keyof T]?: T[P]
}
Exclude
Используется для удаления указанного типа из коллекции типов.
type a = string | number
type newPerson = Exclude<a,string> //number
выполнить:
type Exclude<T, U> = T extends U ? never : T
Readonly
Сделайте все свойства интерфейса доступными только для чтения.
type Person = {
name:string;
sex:string;
}
type newPerson = Readonly<Person>
// type newPerson = {readonly name: string;readonly sex: string;}
выполнить:
type Readonly<T> = { readonly [P in keyof T]: T[P]; }
ReturnType
Роль ReturnType состоит в том, чтобы получить возвращаемый тип функции T.
type T0 = ReturnType<() => string>; // string
type T1 = ReturnType<(s: string) => void>; // void
type T2 = ReturnType<() => T>; // {}
type T3 = ReturnType<() => T>; // number[]
type T4 = ReturnType; // any
type T5 = ReturnType; // any
type T6 = ReturnType; // Error
type T7 = ReturnType; // Error
выполнить:
type ReturnType any> = T extends (...args: any) => infer R ? R : any;
Parameters
Роль параметров заключается в получении типа параметра функции T.
type getuserInfo = (user: string) => void
// Parameters<T>的作用是用于获取函数 T 的参数类型。
type ParametersUserInfo = Parameters<getuserInfo>
Сначала я представлю это здесь. Сейчас я старшеклассник, и в следующем году я пойду в Netease, чтобы передвигать кирпичи. Кодировать слова непросто. Просто поставьте лайк, спасибо.