Когда я впервые столкнулся с машинописным текстом год назад, я почувствовал, что это увеличило нагрузку на код.Я много чего писал.Чтобы найти определенный тип, введение третьей библиотеки часто сообщало об ошибках. Но теперь я хочу сказать: действительно ароматный. Мы часто жалуемся, что ремонтопригодность чужого кода особенно низка, и мы всегда надеемся, что другие могут активно писать комментарии, но нет возможности ограничить написание комментариев. ремонтопригодность.
1. Как решать проблемы, связанные с типами сторонних библиотек
Определения типов сторонних библиотек, предоставляемые Typescipt, не только ограничивают наши входные вызовы, но и предоставляют нам документацию.Теперь в NPM существует так много типов определений сторонних типов, что трудно гарантировать, что определения типов Также трудно гарантировать, что все используемые сторонние библиотеки имеют определения типов. Итак, в этом неизвестном процессе, как правильно использовать сторонние библиотеки в TypeScript? Вот четыре распространенных сценария, которые не работают, и соответствующие решения:
- Сама библиотека не имеет собственного определения типа
- В самой библиотеке нет определений типов и связанных с ними @type.
- неверная библиотека объявления типов
- Ошибка объявления типа
-
Сама библиотека не имеет собственного определения типа Не удалось найти соответствующий тип библиотеки. Например
При преобразовании реакции на поддержку машинописного текста в первый раз многие люди, должно быть, столкнулись с ошибками module.hot.В настоящее время необходимо установить только соответствующую библиотеку типов.Установите @types/webpack-env -
В самой библиотеке нет определений типов и связанных с ними @type. Тогда вы можете объявить только один самостоятельно.Просто дайте каштан.
declare module “lodash”
- неверная библиотека объявления типов
- Нажмите, чтобы разрешить проблемы с определениями официального типа, поднять вопросы, PR
- После импорта исходный тип может быть расширен с возможностью расширения или слияния.
- Терпеть потерю типа или ненадежность
- // @ts-ignore игнорирует
- Ошибка объявления типа
- Добавить «skipLibCheck»: true в компилятореOptions, кривая заставка
2. Используйте сокращение шрифта для устранения ошибок
Существует несколько распространенных решений ниже:
- утверждение типа
- защита типа typeof in instanceof защита типа литерала
- двойное утверждение
1. Утверждение типа Утверждения типа могут явно указать TypeScript подробный тип значения, В некоторых случаях мы очень уверены в его типе, даже если он не соответствует типу, выведенному машинописным текстом, тогда мы можем использовать утверждение типа. Синтаксис следующий:
<类型>值
值 as 类型 // 推荐使用这种语法. 因为<>容易跟泛型, react 中的语法起冲突
Например, в следующем коде значение заполнения может быть либо строкой, либо числом.Хотя в коде написано Array(), мы ясно знаем, что заполнение будет преобразовано в числовой тип с помощью parseint, но определение типа все равно сообщит об ошибке. ошибка.
function padLeft(value: string, padding: string | number) {
// 报错: Operator '+' cannot be applied to
// types 'string | number' and 'number'
return Array(padding + 1).join(" ") + value;
}
В качестве обходного пути используйте утверждение типа.Сообщите машинописному тексту, где я удостоверюсь, что он имеет номер типа, и проигнорируйте ошибку.
function padLeft(value: string, padding: string | number) {
// 正常
return Array(padding as number + 1).join(" ") + value;
}
Но если есть следующая ситуация, нужно ли нам писать много as?
function padLeft(value: string, padding: string | number) {
console.log((padding as number) + 3);
console.log((padding as number) + 2);
console.log((padding as number) + 5);
return Array((padding as number) + 1).join(' ') + value;
}
2. Тип гвардии Существует несколько типов охранников типа, которые вкратце можно описать следующим образом.
- typeof: используется для определения четырех типов «число», «строка», «логическое значение» или «символ».
- instanceof : используется для определения принадлежности экземпляра к классу
- in: используется для определения того, принадлежит ли свойство/метод объекту
- литеральная защита типа
В приведенном выше примере он имеет тип string | number, поэтому typeof используется для защиты типа.Пример выглядит следующим образом:
function padLeft(value: string, padding: string | number) {
if (typeof padding === 'number') {
console.log(padding + 3); //正常
console.log(padding + 2); //正常
console.log(padding + 5); //正常
return Array(padding + 1).join(' ') + value; //正常
}
if (typeof padding === 'string') {
return padding + value;
}
}
По сравнению с утверждением типа as это экономит много кода.В дополнение к typeof у нас есть несколько способов, ниже приведены примеры.
- InstanceOf --- используется для определения принадлежности экземпляра к определенному классу.
class Man {
handsome = 'handsome';
}
class Woman {
beautiful = 'beautiful';
}
function Human(arg: Man | Woman) {
if (arg instanceof Man) {
console.log(arg.handsome);
console.log(arg.beautiful); // error
} else {
// 这一块中一定是 Woman
console.log(arg.beautiful);
}
}
- in --- Используется для определения того, принадлежит ли свойство/метод объекту
interface B {
b: string;
}
interface A {
a: string;
}
function foo(x: A | B) {
if ('a' in x) {
return x.a;
}
return x.b;
}
- литеральная защита типа
В некоторых сценариях использование in, instanceof, typeof слишком затруднительно, в этом случае литеральный тип можно сконструировать самостоятельно.
type Man = {
handsome: 'handsome';
type: 'man';
};
type Woman = {
beautiful: 'beautiful';
type: 'woman';
};
function Human(arg: Man | Woman) {
if (arg.type === 'man') {
console.log(arg.handsome);
console.log(arg.beautiful); // error
} else {
// 这一块中一定是 Woman
console.log(arg.beautiful);
}
}
3. Двойное утверждение Иногда использование as также приводит к ошибке, поскольку утверждение as не является безусловным и может быть успешно утверждено как T, только если тип S является подмножеством типа T или тип T является подмножеством типа S. Итак, перед лицом этой ситуации, если вы просто хотите решить проблему насильственно, вы можете использовать двойное утверждение.
function handler(event: Event) {
const element = event as HTMLElement;
// Error: 'Event' 和 'HTMLElement' 中的任何一个都不能赋值给另外一个
}
Если вы все еще хотите использовать этот тип, вы можете использовать двойное утверждение. Сначала утверждается, что он совместим со всеми типами любого
function handler(event: Event) {
const element = (event as any) as HTMLElement; // 正常
}
3. Используйте последние функции js, поддерживаемые машинописным текстом, для оптимизации кода.
- Необязательная цепочка
let x=foo?.bar.baz();
Реализация на машинописном языке выглядит следующим образом:
var _a;
let x = (_a = foo) === null || _a === void 0 ? void 0 : _a.bar.baz();
Используя эту функцию, мы можем сохранить много неприятного кода, такого как && a.b && a.b.c.
- Нулевое слияние
let x =foo ?? '22';
Реализация на машинописном языке выглядит следующим образом:
let x = (foo !== null && foo !== void 0 ? foo : '22');
4. Используйте расширенные типы для гибкой обработки данных
Typescript предоставляет несколько очень хороших служебных функций, как показано ниже.
- индекс типа
Чтобы реализовать вышеуказанную служебную функцию, нам нужно понять следующий синтаксис: keyof : получить значение ключа для типа extends : ограничения в дженериках T[K] : получить тип элемента соответствующего K объекта T
type Partial<T> = {
[P in keyof T]?: T[P]
}
При использовании props иногда все свойства необязательны.Если писать ? по одному, много повторяющихся действий.В этом случае можно использовать Partial напрямую
Запись — очень гибкий инструмент, первый универсальный тип передается в значении ключа объекта, а второй — в значении свойства объекта.
type Record<K extends string, T> = {
[P in K]: T;
}
Давайте посмотрим на этот объект ниже, как бы вы объявили его с помощью ts?
const AnimalMap = {
cat: { name: '猫', title: 'cat' },
dog: { name: '狗', title: 'dog' },
frog: { name: '蛙', title: 'wa' },
};
Вы можете использовать запись в это время.
type AnimalType = 'cat' | 'dog' | 'frog';
interface AnimalDescription { name: string, title: string }
const AnimalMap: Record<AnimalType, AnimalDescription> = {
cat: { name: '猫', title: 'cat' },
dog: { name: '狗', title: 'dog' },
frog: { name: '蛙', title: 'wa' },
};
- никогда, создает условные типы
В дополнение к приведенным выше синтаксисам мы также можем использовать never , сконструировать условные типы для составления более гибких определений типов.
грамматика:
never: 从未出现的值的类型
// 如果 T 是 U 的子类型的话,那么就会返回 X,否则返回 Y
构造条件类型 : T extends U ? X : Y
type Exclude<T, U> = T extends U ? never : T;
// 相当于: type A = 'a'
type A = Exclude<'x' | 'a', 'x' | 'y' | 'z'>
- Более лаконичные модификаторы: - и + Вы можете напрямую удалить ?, чтобы сделать все свойства объекта обязательными.
type Required<T> = { [P in keyof T]-?: T[P] };
// Remove readonly
type MutableRequired<T> = { -readonly [P in keyof T]: T[P] };
- infer: переменная типа для вывода в условном операторе extends.
// 需要获取到 Promise 类型里蕴含的值
type PromiseVal<P> = P extends Promise<infer INNER> ? INNER : P;
type PStr = Promise<string>;
// Test === string
type Test = PromiseVal<PStr>;
5. Определите тип и интерфейс
В основных библиотеках типов вы увидите всевозможные типы и интерфейсы, однако на практике многие люди не знают разницы между ними.
Определение официального сайта выглядит следующим образом:
An interface can be named in an extends or implements clause, but a type alias for an object type literal cannot.
An interface can have multiple merged declarations, but a type alias for an object type literal cannot.
Посмотрите разницу между ними на картинке:
Рекомендация: может быть реализован с интерфейсом, использует интерфейс, если вы не можете использовать тип.
6. Постоянное перечисление
Для конфиденциальных данных можно использовать постоянный метод перечисления.
const enum learn {
math,
language,
sports
}
После компиляции он пустой:
Когда нам не нужен объект, но нужно значение, мы можем использовать этот метод, который может сократить код времени выполнения следующим образом:Прошлые статьи:
- Основные типы машинописи
- Перечисления машинописного текста
- Интерфейс машинописного текста
- Универсальные машинописные тексты
- Функции и классы машинописного текста
- Лучшие практики машинописного текста
Добро пожаловать, чтобы обратить внимание на «Front-end Plus», серьезно изучить интерфейс и стать профессиональным техником...