МАШИНОПИСЬ

Вы должны избегать этих ошибок машинописного текста

Привет ребята! давно не писал. Надеюсь, вам понравится эта статья. Эта статья будет об ошибках Typescript. Давайте начнем.

Используйте «неизвестно» вместо «любой»

any и unknown одинаковы с точки зрения того, что им можно присвоить, но отличаются тем, что unknown нельзя присвоить ничему, кроме any. Итак, давайте посмотрим на эти два типа

'любой тип

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

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

«неизвестный» тип

Тип unknown представляет значение any. Это похоже на тип any, но безопаснее, потому что нельзя ничего делать со значением unknown:

function f1(a: any) {
  a.b(); // OK
}
function f2(a: unknown) {
  a.b(); // We'll get an error.
 // Object is of type 'unknown'.
}

В этой ситуации мы должны использовать unknown, если мы не хотим ошибки времени выполнения.

Давайте посмотрим на реальный пример между двумя типами;

/*
We have a fetch structure for getting data from Backend. 
Also, We have a User interface and an AdminUser interface. 
We send a request and get the User but, 
we don’t know the user’s type, Right? 
So We should use the Unknown type for that.
*/

interface IUser{
 id: string;
 firstName: string;
 lastName: string;
 email: string;
 userName: string;
}

interface IAdminUser extends IUser {
 token: string;
 addNewUser: ()=>void;
}

function isAdminUser(object: unknown): object is IAdminUser {
 if(object !==null && typeof object === "object"){
  return "token" in object;
 }
 return false;
}

function isNormalUser(object: unknown): object is IUser {
 if(object !==null && typeof object === "object"){
  return "token" !in object;
 }
 return false;
}

async function fetchUser(){
 const response = await fetch("localhost:3000/getUser/1");

 //Bad using
 const badUser: any = await response.json();
/*
 I can acsess and Dont get an error but We dont 
 known the user type and If the user is normal user 
 I'll get an error on runtime.
*/ 
 badUser.addNewUser()
 //------

 // Best Practice

 const bestUser : unknown = await response.json();
 if(isAdminUser(bestUser)){
  bestUser.addNewUser() //We'll not get an error. And We can know the type.
 } 
 if(isNormalUser(bestUser)){
  bestUser.addNewUser() // We got an error when we coding, not at runtime.
 } 
}

Используйте оператор «есть»

Boolean — это просто тип данных, а оператор is используется для проверки типов. Когда мы используем оператор is, мы говорим машинописному тексту «эй! Проверь это'

Давайте посмотрим на это поближе;

type Species = 'cat' | 'dog';

interface Pet {
    species: Species;
}

class Cat implements Pet {
    public species: Species = 'cat';
    public meow(): void {
        console.log('Meow');
    }
}

function petIsCat(pet: Pet): pet is Cat {
    return pet.species === 'cat';
}

function petIsCatBoolean(pet: Pet): boolean {
    return pet.species === 'cat';
}

const p: Pet = new Cat();

p.meow(); // ERROR: Property 'meow' does not exist on type 'Pet'.

if (petIsCat(p)) {
    p.meow(); 
// now compiler knows for sure that the variable is of type Cat and it has meow method
}

if (petIsCatBoolean(p)) {
    p.meow(); // ERROR: Property 'meow' does not exist on type 'Pet'.
}

Используйте оператор «удовлетворяет»

Целью satisfies является принудительное ограничение переменной без изменения ее типа.

interface ICustomImage{
 data: string;
 width: number;
 height: number;
}

type UserImage = string | ICustomImage;

interface IUser{
 id: number;
 firstName: string;
 lastName: string;
 image: UserImage;
}

//bad usage
const badUser : IUser= {
 id:1,
 firstName: 'Kadir Osman',
 lastName: 'Ust',
 image: 'image/url'
}

// You cannot know the type of the image and cannot use the string methods as well.
badUser.image

const gooUser = {
 id:1,
 firstName: 'Kadir Osman',
 lastName: 'Ust',
 image: 'image/url'
} satisfies IUser;

// Now, You can use string method.

Используйте типы утилит

Существует множество типов утилит. Мы не будем говорить обо всех из них. Но некоторые из них действительно важны для нас. Это Partial<type>, Required<type>, Omit<type,keys>, Readonly<type>; Давайте посмотрим на это;

Что такое Частичный‹тип›?

Partial — создатель типа. Создает тип со всеми свойствами type, установленными как необязательные. Эта утилита вернет тип, представляющий все подмножества данного типа. Он ведет себя так, как будто все свойства являются необязательными. Давайте посмотрим на это внимательно;

type User ={
  username : string
  name : string
}

const ourUser: Partial<User> = {
 name: 'Kadir'
}

Что такое Требуемый‹тип›?

Создает тип, состоящий из всех свойств type, установленных как обязательные. Противоположность Partial<type>.

interface Props {
  a?: number;
  b?: string;
}
 
const obj: Props = { a: 5 };
 
const obj2: Required<Props> = { a: 5 };
/* 
error: Property 'b' is missing in type '{ a: number; }' 
but required in type 'Required<Props>'. 
*/

Что такое Omit‹type, keys›?

Создает тип, выбирая все свойства из type и затем удаляя keys (строковый литерал или объединение строковых литералов).

Давайте посмотрим на пример. Слишком много свойств. Если мы не хотим отправлять id prop и создавать новый тип или интерфейс только для него, мы можем его опустить. Например ;

interface IFirm {
 id: string;
 name: string;
}

const ourData : Omit<IFirm,'id'> =  {
 name : 'Kardesler Yazilim'
}

Что такое «Только для чтения»?

Создает тип со всеми свойствами Type, установленными на readonly, что означает, что свойства созданного типа нельзя переназначить.

interface Todo {
  title: string;
}
 
const todo: Readonly<Todo> = {
  title: "Delete inactive users",
};
 
todo.title = "Hello";
/*
Cannot assign to 'title' because it is a read-only property.
*/

Эта утилита полезна для представления выражений присваивания, которые завершатся ошибкой во время выполнения (т. е. при попытке переназначить свойства замороженного объекта).

Надеюсь увидеть вас в других статьях.

›REF