Примечания к Typescript

  • неизвестный тип функционирует как any, но не позволяет вызывать метод данных Typescript выдаст ошибку времени компиляции, так как мы используем строковую функцию без утверждения типа. Чтобы исправить это, правильный код будет выглядеть следующим образом
 function readAny(val: unknown){

    if( typeof val === 'string')
     return val.trim();
}
Вход в полноэкранный режим Выйти из полноэкранного режима
  • для проверки использования null/undefined, == например.
if(value == null) // check for both null and undefined
Войти в полноэкранный режим Выйти из полноэкранного режима
  • пересечение типов (&) ведет себя как наследование в классах, то есть атрибуты одного типа наследуются другим типом, не вызывая дублирования
  • пример:
type Point2d = {
  x: number;
  y:number;
}

type Point3d = Point2d & {
  z:number;
}

const p1: Point2d = {x: 1, y:2}
const p2: Point3d = {x: 1, y:2, z: 9}

Войти в полноэкранный режим Выход из полноэкранного режима

точка 3D имеет все члены точки 2D плюс член z. Все члены в типах пересечения являются обязательными. Если не передать «z» в типе Point3D, это приведет к ошибке.

  • Тип Union определяется оператором pipe «|». Это означает, что тип может быть как отдельным типом, так и их комбинацией. Все свойства комбинации необязательны
interface A {
  a1: string,
  a2: string,
}

interface B {
  b1: string,
  b2: string;
}

type UnionAB = A | B;


const unionAB1: UnionAB = {
  a1: 'xxx',
  a2: 'xxx',
  b1: 'xxx',
  b2: 'xxx',
};

const unionAB2: UnionAB = {
  a1: 'xxx',
  a2: 'xxx',
};

const unionAB3: UnionAB = {
  b1: 'xxx',
  b2: 'xxx',
};

// Error
// Property 'a1' does not exist on type 'B'.
console.log(unionAB3.a1);

const unionAB4: UnionAB = {
  a1: 'xxx',
  a2: 'xxx',
  b2: 'xxx',
};

// Error
// Property 'b1' does not exist on type 'UnionAB'.
// Property 'b1' does not exist on type 'A'.
console.log(unionAB4.b1);


// Error
// Type '{ a1: string; b2: string; }' is not assignable to type 'UnionAB'.
// Property 'b1' is missing in type '{ a1: string; b2: string; }' but required in type 'B'.
const unionAB5: UnionAB = {
  a1: 'xxx',
  b2: 'xxx',
};

Вход в полноэкранный режим Выйти из полноэкранного режима
  • необязательные переменные в типе обозначаются символом «?» . Это означает, что значения могут передаваться или не передаваться. работает на переменных класса как пример:
type PointXd = {
  x: number;
  y:number;
  z?:number;
}

const p1: PointXd = {x: 1, y:2}
const p2: PointXd = {x: 1, y:2, z: 5}

console.log(p1)
console.log(p2)
Войти в полноэкранный режим Выход из полноэкранного режима
  • Буквальные типы — Эта функция позволяет создавать набор значений отношений.
type Direction = "North" | "South" | "East" | "West";
Вход в полноэкранный режим Выход из полноэкранного режима

Буквальные типы в этом случае создают также Type Guard вашего поля, так что компилятор может обнаружить ваши ошибки или опечатки.

let directionError: Direction = "east" // Type '"east"' is not assignable to type 'Direction'
let direction: Direction = "East" // OK

Войти в полноэкранный режим Выйти из полноэкранного режима
  • Оператор keyof помогает нам извлекать свойства объекта, такие как литеральные типы
type Person = {
  age: number;
  phone: string;
}

type PersonKeys = keyof Person; // "age" | "phone" 

usage with in operator to set all fields to number

type Student = {
  [key in keyof Person]: number ;
}


const student: Student = {
age: 18,
phone: "1252672"    // Type 'string' is not assignable to type 'number'
}

Войти в полноэкранный режим Выйти из полноэкранного режима
  • дискриминируемые типы
    пример

  • Утверждение not null может быть сделано с помощью оператора «!».
    пример: https://dev.to/this-is-learning/typescript-tips-tricks-non-null-assertion-operator-21eb

  • Интерфейс и тип в некотором роде одно и то же, но типы предлагают больше возможностей. & можно заменить на extends для интерфейса.

  • Интерфейс поддерживает объединение деклараций, которое аналогично объединению в типах. Если существуют два интерфейса с одинаковыми именами, то их тело объединяется.
    пример:

interface Person {
  name: string;
}

interface Person{
  age: number
}

const person: Person =  {name: 'Max', age: 27}; // merged into a single Person interface

console.log(person);

Войти в полноэкранный режим Выход из полноэкранного режима
  • никогда не видеть тип
  • Когда класс реализует тип/интерфейс, он должен иметь все атрибуты, упомянутые в интерфейсе/типе. Это действует как пример чертежа:
type Person = {
  age: number;
  phone: string;
}

  // Error below: Type 'Student' is missing the following properties from type 'Person': age, phone

class Student implements Person{   
  id: string
}



Вход в полноэкранный режим Выход из полноэкранного режима
  • окончательное присвоение(!) используется, чтобы сказать typescript, что значение будет определено, и вы должны убедиться, что оно определено.

let person: string


 function test(){
  person = "rubin"
 }

 test()

 console.log(person)  // error TS2454: Variable 'person' is used before being assigned.

Even though person is initialized inside the test function, typescript doesnot know this. 
To tell typescript that this value will always be non null,  add "!" and the error goes away

let person!: string



Вход в полноэкранный режим Выход из полноэкранного режима
  • Охрана типов используется с ключевым словом «is» и служит для утверждения, что значение имеет определенный тип.
type Rectangle ={
    length: number,
    breadth: number
}


type Square ={
  size: number
}

type Shape = Rectangle | Square;

function isRectangle(shape: Shape): shape is Rectangle {
  return "length" in shape && "breadth" in shape;
}

function isSquare(shape: Shape): shape is Square{
  return "size" in shape;
}


function printArea(shape: Shape) {
    if (isRectangle(shape)) {
        console.log(shape.length * shape.breadth);
    }
    if(isSquare(shape)){
      console.log(shape.size * shape.size);
    }


}

Here we are telling typescript if the function returns true, 
the value is of type "Person"


Notice: the guard can also be defined as 
function isSquare(shape: Shape): boolean{
  return "size" in shape;
}

However typescript wont know the shape is "Square" even if it returns true
so its best to use the above for type checking



Вход в полноэкранный режим Выход из полноэкранного режима
  • Абстрактный класс обычно используется для определения общего поведения производных классов. В отличие от обычного класса, абстрактный класс не может быть создан напрямую. Нереализованные методы должны быть реализованы и определены классами, которые его расширяют.
abstract class Logger{
 abstract prefix(): string

log(message: string){
    console.log(this.prefix() +":"+ message)
}
}

class ConsoleLogger extends Logger{
  prefix(): string {
      return "Console"
  }

}

const logger = new ConsoleLogger()
logger.log("Hello")

Вход в полноэкранный режим Выйти из полноэкранного режима
  • К объекту в js можно обращаться с помощью индексной подписи, т.е. Obj[key], подобно массиву. В typescript мы можем определить тип индекса при доступе к значениям объекта.
type Person= {
  userName: string;
  address: string;
}

const p1: Person = {
  userName: 'alex123',
  address: '123 Main St.',
}
const p2: Person = {
  userName: 'ryan123',
  address: '123 Main St.',
}


type PersonDictionary= {
  [key: string]: Person
}

const persons: PersonDictionary = {
  alex: p1,
  ryan: p2
}

persons['alex'].userName = 'alex567' 

console.log(persons['alex'])

Вход в полноэкранный режим Выйти из полноэкранного режима
  • Кортежи — это массивы с фиксированной длиной.

  • Общие ограничения используются для того, чтобы потребовать, чтобы общие параметры имели определенную структуру. Если вы не укажете их и попытаетесь получить доступ к свойству данных, typescript выдаст ошибку, так как не знает структуры данных.

const addFullName = <T>(obj: T) => {
  return {...obj, fullName: `${obj.firstName} ${obj.lastName}`};
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Здесь мы определили параметр типа generic T. Если мы попытаемся получить доступ к свойствам параметра,
даже если он существует, мы получим ошибку типа Property 'lastName' does not exist on type 'T'. Мы можем исправить это, добавив ограничения generic, которые говорят typescript, что generic имеет эти свойства. Кроме того, он также требует, чтобы передаваемое значение имело свойства firstName и lastName.

type NamedVales = {firstName: string, lastName: string};

const addFullName = <T extends NamedVales>(obj: T) => {
  return {...obj, fullName: `${obj.firstName} ${obj.lastName}`};
}
Вход в полноэкранный режим Выйти из полноэкранного режима
  • Ключ typeof может быть использован для извлечения типа из существующих данных
const user = {
  name: "Rubin",
  age: 15,
  address: "Kathmandu"
}

type UserType = typeof user  //  {name: string,age:number,address: string}
Войти в полноэкранный режим Выход из полноэкранного режима

-Типы поиска используются для извлечения части из сложного типа и создания нового типа

type requestType = {

  payload: {
    name: string,
    user: number,
    roles: {
      edit: boolean,
      create: boolean,
      read: boolean
    }
  },
   params: {
     id: number,
     type: string
   }
}

// if we want to use type of  params as a type then

type Params = requestType["params"]  //  {id: number,type: string }
type Roles = requestType["payload"]["roles"] //   roles: {edit: boolean,create: boolean,read: boolean}

Войти в полноэкранный режим Выход из полноэкранного режима

Оцените статью
Procodings.ru
Добавить комментарий