Пусть & # 39; s закончить то, что мы начали

Расширенный тип

  1. https://www.tslang.cn/docs/handbook/advanced-types.html
  2. Кросс тип (типы пересечений), множество типов в один тип.

    Например, лицо & Сериализуемый & Loggable также Человек и Сериализуемый и Loggable. То есть объект этого типа имеет три типа элементов.

    function extend<First, Second>(first: First, second: Second): First & Second {
       const result: Partial<First & Second> = {};
       for (const prop in first) {
          if (first.hasOwnProperty(prop)) {
             (result as First)[prop] = first[prop];
          }
       }
       for (const prop in second) {
          if (second.hasOwnProperty(prop)) {
             (result as Second)[prop] = second[prop];
          }
       }
       return result as First & Second;
    }
        
    class Person {
       constructor(public name: string) { }
    }
        
    interface Loggable {
       log(name: string): void;
    }
        
    class ConsoleLogger implements Loggable {
       log(name) {
          console.log(`Hello, I'm ${name}.`);
       }
    }
        
    const jim = extend(new Person('Jim'), ConsoleLogger.prototype);
    jim.log(jim.name);
    
  3. Тип соединения представляет собой значение может быть один из нескольких типов. Мы используем вертикальную полосу (|) для разделения каждого типа, число | строка | логическое значение представляет собой значение может быть числом, строка или логическое значение.

    function padLeft(value: string, padding: string | number) {
        // ...
    }
        
    let indentedString = padLeft("Hello world", true); // errors during compilation
    

    Если значение типа союза, принадлежит к тому, что особенно до типа типа профсоюзным значения неопределенности, мы можем получить доступ всех видов этого типа членов профсоюза в целом.

  4. interface Bird {
        fly();
        layEggs();
    }
        
    interface Fish {
        swim();
        layEggs();
    }
        
    function getSmallPet(): Fish | Bird {
        // ...
    }
        
    let pet = getSmallPet();
    pet.layEggs(); // okay
    pet.swim();    // errors
    pet.layEggs(); // errors
    

    Тип защиты, что некоторые выражения, они будут проверять, чтобы убедиться, что тип во время выполнения в объеме внутри.

    function isFish(pet: Fish | Bird): pet is Fish {
        return (<Fish>pet).swim !== undefined;
    }
    

    животное Рыба является типом предиката. ИмяПараметра является типом предиката к этой форме, имяПараметр должен быть выведен из текущей функции имени параметра в подписи.

    // 'swim' 和 'fly' 调用都没有问题了
        
    if (isFish(pet)) {
        pet.swim();
    }
    else {
        pet.fly();
    }
    
    • TypeOf тип защиты

    TypeOf тип защит может быть определена только две формы: TypeOf v === «Ьурепат» и TypeOf v == «Ьурепат», «Ьурепат» должен быть «номер», «строка», «логическим» или «символ» !. Но машинопись не мешает сравнивать с другими строками, не ставьте эти языковые выражения, признанное в качестве типа защиты.

    function padLeft(value: string, padding: string | number) {
        if (typeof padding === "number") {
            return Array(padding + 1).join(" ") + value;
        }
        if (typeof padding === "string") {
            return padding + value;
        }
        throw new Error(`Expected string or number, got '${padding}'.`);
    }
    
    • в операторе

    п х, п определяется, является ли атрибут х, возвращает истинным или ложным.

    function move(pet: Fish | Bird) {
        if ("swim" in pet) {
            return pet.swim();
        }
        return pet.fly();
    }
    
    • InstanceOf тип защиты

    InstanceOf права требования является конструктором (конструктор рафинированного типа), машинопись подразделяется на: 1. Типа прототипа типа конструктора свойства, если это не так, то любая, структура 2. подписи тип совместного возвращения

    interface Padder {
       getPaddingString(): string
    }
        
    class SpaceRepeatingPadder implements Padder {
       constructor(private numSpaces: number) { }
       getPaddingString() {
          return Array(this.numSpaces + 1).join(" ");
       }
    }
        
    class StringPadder implements Padder {
       constructor(private value: string) { }
       getPaddingString() {
          return this.value;
       }
    }
        
    function getRandomPadder() {
       return Math.random() < 0.5 ?
          new SpaceRepeatingPadder(4) :
          new StringPadder("  ");
    }
        
    // 类型为SpaceRepeatingPadder | StringPadder
    let padder: Padder = getRandomPadder();
        
    if (padder instanceof SpaceRepeatingPadder) { // 类型细化为'SpaceRepeatingPadder'
       // ...
    }
    if (padder instanceof StringPadder) { // 类型细化为'StringPadder'
       // ...
    }
    
  5. По умолчанию, типа проверка считается недействительной и неопределенной может быть назначена для любого типа. нуль и неопределенным является допустимым значением для всех других типов.

    -strictNullChecks знак

    1. При объявлении переменной, она автоматически не содержит нуль или не определено
    2. Дополнительные параметры будут автоматически добавить | неопределенными
  6. Идентификатор! От типа идентификатора идти, кроме нулевого и неопределенного (идентификатора утверждения не существует нуля и не определен).

  7. Тип псевдоним не будет создавать новый тип (на самом деле создает новое имя для обозначения типа). Иногда подобный интерфейс типа псевдоним, но это можно назвать примитивным, суставов, и любой другой тип кортежа вы должны вручную писать.

    type Name = string;
    type NameResolver = () => string;
    type NameOrResolver = Name | NameResolver;
    function getName(n: NameOrResolver): Name {
        if (typeof n === 'string') {
            return n;
        }
        else {
            return n();
        }
    }
    

    Псевдонимы могут быть также общий тип

    type Tree<T> = {
        value: T;
        left: Tree<T>;
        right: Tree<T>;
    }
    

    Тип псевдонимы не могут появляться в любом месте на праве заявления

    type Yikes = Array<Yikes>; // error
    
  8. Интерфейс против псевдонима типа

    1. Интерфейс для создания нового имени может быть использован в любом другом месте. Тип псевдоним не создает новое имя - например, сообщение об ошибке не будет использовать псевдонимы.
    2. Тип псевдоним не может быть распространяется и реализует (сам не распространяется, и другие типы орудий, открытый закрытый принцип ), интерфейс должны быть использован вместо типа псевдонима.
    3. Если не в состоянии описать тип или тип и требует использование кортежей в сочетании, то типа обычно используются псевдонимы интерфейсов.

      type Name = string;
      type NameResolver = () => string;
      type NameOrResolver = Name | NameResolver;
      function getName(n: NameOrResolver): Name {
          if (typeof n === 'string') {
              return n;
          }
          else {
              return n();
          }
      }
      
  9. Строка литерала типа позволяет указать строка должна быть фиксированной величиной.

    type Easing = "ease-in" | "ease-out" | "ease-in-out";
    class UIElement {
       animate(dx: number, dy: number, easing: Easing) {
          if (easing === "ease-in") {
             // ...
          }
          else if (easing === "ease-out") {
          }
          else if (easing === "ease-in-out") {
          }
          else {
             // error! should not pass null or undefined.
          }
       }
    }
        
    let button = new UIElement();
    button.animate(0, 0, "ease-in");
    button.animate(0, 0, "uneasy"); // error: "uneasy" is not allowed here
    

    Строковые литералы могут также использоваться, чтобы отличить тип функции перегрузки

  10. Цифровой буквальный тип

    function foo(x: number) {
        if (x !== 1 || x !== 2) {
            //         ~~~~~~~
            // Operator '!==' cannot be applied to types '1' and '2'.
        }
    }
    
  11. Когда каждый из членов перечисления инициализируются с буквальным элементом перечисления является типом. Большинство одноточечного типа относится к элементу типа и числовое перечисления / String буквального типа.

  12. Это может быть объединено одноэлементными типы, типы профсоюзов, тип защиты и типа псевдонимов, чтобы создать расширенный режим под названием дискриминированного объединение, его также называют тегами объединения или алгебраическими типами данных.

    • Пример обычный атрибут одного типа - отличительные черты.
    • Тип псевдоним содержит те виды совместного - сустав.
    • В этом типе защиты собственности.

      // kind属性称做 可辨识的特征或 标签。
      interface Square {
          kind: "square";
          size: number;
      }
      interface Rectangle {
          kind: "rectangle";
          width: number;
          height: number;
      }
      interface Circle {
          kind: "circle";
          radius: number;
      }
              
      type Shape = Square | Rectangle | Circle;
          
      function area(s: Shape) {
          switch (s.kind) {
              case "square": return s.size * s.size;
              case "rectangle": return s.height * s.width;
              case "circle": return Math.PI * s.radius ** 2;
          }
      }
      

    Когда не охватывают все узнаваемые совместные изменения, необходимость проверки целостности.

    1. Возвращаемое значение оценивается по количеству или не определено

      type Shape = Square | Rectangle | Circle | Triangle;
      function area(s: Shape) {
          switch (s.kind) {
              case "square": return s.size * s.size;
              case "rectangle": return s.height * s.width;
              case "circle": return Math.PI * s.radius ** 2;
          }
          // should error here - we didn't handle case "triangle"
      }
      
    2. Никогда не используйте тип

      function assertNever(x: never): never {
          throw new Error("Unexpected object: " + x);
      }
      function area(s: Shape) {
          switch (s.kind) {
              case "square": return s.size * s.size;
              case "rectangle": return s.height * s.width;
              case "circle": return Math.PI * s.radius ** 2;
              default: return assertNever(s); // error here if there are missing cases
          }
      }
      
  13. Это представляет собой полиморфизм типа, содержащий специальный подкласс или интерфейс типа. Это называется F-ограниченный полиморфизм, который легко производительность наследования между когерентным интерфейсом.

  14. keyof Т, операторы запроса типа индекса. Для любого типа Т, результат известен keyof T T суставу на имена государственной собственности.

        interface Person {
            name: string;
            age: number;
        }
            
        let personProps: keyof Person; // 'name' | 'age'
    
  15. Т [К], оператор доступа индекс. (Например: человек [ 'имя'])

        function getProperty<T, K extends keyof T>(o: T, name: K): T[K] {
            return o[name]; // o[name] is of type T[K]
        }
            
        let name: string = getProperty(person, 'name');
        let age: number = getProperty(person, 'age');
        let unknown = getProperty(person, 'unknown'); // error, 'unknown' is not in 'name' | 'age'
    
  16. Типы отображения

    interface PersonPartial {
        name?: string;
        age?: number;
    }
        
    interface PersonReadonly {
        readonly name: string;
        readonly age: number;
    }
    

    Эквивалент

    interface Person {
        name: string;
        age: number;
    }
        
    type Readonly<T> = {
        readonly [P in keyof T]: T[P];
    }
    type Partial<T> = {
        [P in keyof T]?: T[P];
    }
        
    type PersonPartial = Partial<Person>;
    type ReadonlyPerson = Readonly<Person>;
    
    type Keys = 'option1' | 'option2';
    type Flags = { [K in Keys]: boolean };
        
    //type Flags = {
    //      option1: boolean;
    //      option2: boolean;
    //  }
    
  17. Гомоморфный тип, не создает новые свойства.

    type Pick<T, K extends keyof T> = {
        [P in K]: T[P];
    } // 同态
    type Record<K extends string, T> = {
        [P in K]: T;
    } // 非同态,它们不会从它处拷贝属性修饰符
        
    type ThreeStringProps = Record<'prop1' | 'prop2' | 'prop3', string>
    
  18. Состояние Тип

    Увеличение способности выражать неравномерные отображения типов. Состояние Тип выбрать один из двух возможных типов тестирования как условие типа отношений, основанного на представлении.

    T extends U ? X : Y
    
  19. Предопределенные условный тип

    type T00 = Exclude<"a" | "b" | "c" | "d", "a" | "c" | "f">;  // "b" | "d"
    type T01 = Extract<"a" | "b" | "c" | "d", "a" | "c" | "f">;  // "a" | "c"
        
    type T02 = Exclude<string | number | (() => void), Function>;  // string | number
    type T03 = Extract<string | number | (() => void), Function>;  // () => void
        
    type T04 = NonNullable<string | number | undefined>;  // string | number
    type T05 = NonNullable<(() => string) | string[] | null | undefined>;  // (() => string) | string[]
        
    function f1(s: string) {
        return { a: 1, b: s };
    }
        
    class C {
        x = 0;
        y = 0;
    }
        
    type T10 = ReturnType<() => string>;  // string
    type T11 = ReturnType<(s: string) => void>;  // void
    type T12 = ReturnType<(<T>() => T)>;  // {}
    type T13 = ReturnType<(<T extends U, U extends number[]>() => T)>;  // number[]
    type T14 = ReturnType<typeof f1>;  // { a: number, b: string }
    type T15 = ReturnType<any>;  // any
    type T16 = ReturnType<never>;  // any
    type T17 = ReturnType<string>;  // Error
    type T18 = ReturnType<Function>;  // Error
        
    type T20 = InstanceType<typeof C>;  // C
    type T21 = InstanceType<any>;  // any
    type T22 = InstanceType<never>;  // any
    type T23 = InstanceType<string>;  // Error
    type T24 = InstanceType<Function>;  // Error
    

    Исключить типом является реализация Diff типа предложения. Мы используем Исключено это имя, чтобы избежать повреждений Diff код был определен, и мы считаем это имя лучше выразить тип семантики. Мы не опускаем увеличить Тип, потому что он может быть легко использован Пика > Для представления.

  20. Проверка типа является параметр типа голого типа условий называют условия типа роздан. Распределенные условия типа во время конкретизации автоматически распределяется по типу объединения.

    type BoxedValue<T> = { value: T };
    type BoxedArray<T> = { array: T[] };
    type Boxed<T> = T extends any[] ? BoxedArray<T[number]> : BoxedValue<T>;
        
    type T20 = Boxed<string>;  // BoxedValue<string>;
    type T21 = Boxed<number[]>;  // BoxedArray<number>;
    type T22 = Boxed<string | number[]>;  // BoxedValue<string> | BoxedArray<number>;
    

    Свойства распределения типа условия могут быть удобно использовать для фильтрации комбинированного типа:

    type Diff<T, U> = T extends U ? never : T;  // Remove types from T that are assignable to U
    type Filter<T, U> = T extends U ? T : never;  // Remove types from T that are not assignable to U
        
    type T30 = Diff<"a" | "b" | "c" | "d", "a" | "c" | "f">;  // "b" | "d"
    type T31 = Filter<"a" | "b" | "c" | "d", "a" | "c" | "f">;  // "a" | "c"
    type T32 = Diff<string | number | (() => void), Function>;  // string | number
    type T33 = Filter<string | number | (() => void), Function>;  // () => void
        
    type NonNullable<T> = Diff<T, null | undefined>;  // Remove null and undefined from T
        
    type T34 = NonNullable<string | number | undefined>;  // string | number
    type T35 = NonNullable<string | string[] | null | undefined>;  // string | string[]
        
    function f1<T>(x: T, y: NonNullable<T>) {
        x = y;  // Ok
        y = x;  // Error
    }
        
    function f2<T extends string | undefined>(x: T, y: NonNullable<T>) {
        x = y;  // Ok
        y = x;  // Error
        let s1: string = x;  // 严格模式下报错,正常不报错
        let s2: string = y;  // Ok
    }
    

    Тип Mapping используется в сочетании с типом ссылки условия :( разрешен их рекурсивен)

    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[] }
    
    type ElementType<T> = T extends any[] ? ElementType<T[number]> : T;  // Error
    
  21. Тип вывода типов условий распространяется в типе условий пунктов, в настоящее время могут быть объявлены Infer (функция Infer можно использовать для вывода параметров или возвращаемых значений), которые будут введены в выведенной типа переменной. Такой вывод может ссылаться на тип переменных типа истинное состояние отрасли. вывести множество позиций может быть предусмотрено для того же самого типа переменных.

    type Unpacked<T> =
        T extends (infer U)[] ? U :
        T extends (...args: any[]) => infer U ? U :
        T extends Promise<infer U> ? U :
        T;
        
    type T0 = Unpacked<string>;  // string
    type T1 = Unpacked<string[]>;  // string
    type T2 = Unpacked<() => string>;  // string
    type T3 = Unpacked<Promise<string>>;  // string
    type T4 = Unpacked<Promise<string>[]>;  // Promise<string>
    type T5 = Unpacked<Unpacked<Promise<string>[]>>;  // string
    
    type TTuple = [string, number];
    type Res = TTuple[number]; // string | number,类型互转 tuple 转 union
    

    Несколько мест одного и того же типа переменной ковариат кандидатов, как вести союз типа выведенный:

    type Foo<T> = T extends { a: infer U, b: infer U } ? U : never;
    type T10 = Foo<{ a: string, b: string }>;  // string
    type T11 = Foo<{ a: string, b: number }>;  // string | number
    

    Анти множество кандидатов переменной позиции приведет к тому же типу кросс-типа переменного выводятся:

    type Bar<T> = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U : never;
    type T20 = Bar<{ a: (x: string) => void, b: (x: string) => void }>;  // string
    type T21 = Bar<{ a: (x: string) => void, b: (x: number) => void }>;  // string & number
    

    Если (например, тип перегрузки функций) выводится из типа, имеющего множество подписи вызова из последней подписи (может быть случай, самый либеральный из всех захвачена) быть выведены. Вы не можете выполнить разрешение перегрузки на основе списка типов параметров.

    declare function foo(x: string): number;
    declare function foo(x: number): string;
    declare function foo(x: string | number): string | number;
    type T30 = ReturnType<typeof foo>;  // string | number
    

    вывести параметры обычного типа, не представляется возможное в предложении ограничения декларации Тем не менее, путем стирания типа переменных и условия ограничения для указанного типа, по существу, тот же эффект может быть получен:

    type ReturnType<T extends (...args: any[]) => infer R> = R;  // Error, not supported
    
    type AnyFunction = (...args: any[]) => any;
    type ReturnType<T extends AnyFunction> = T extends (...args: any[]) => infer R ? R : any;
    

Оригинал: Big Box  Давайте закончим то , что начали


рекомендация

отwww.cnblogs.com/petewell/p/11421947.html