Эта статья — вольный перевод свежего стрима ThePrimeTimeagen (бывший разработчик Netflix, харизматичный чувак с усами)
«I’m just the normy, but everyone is so bad at their crap, so I just rise to the top»
Цитата:
«Я просто обычный разработчик, но все вокруг настолько плохо справляются со своей работой, что на их фоне я кажусь топовым»
Я понимаю что вся эта информация в текстовом виде не очень то похожа на стендап, поэтому очень советую посмотреть оригинальный стрим. Многие примеры я видела впервые и мне было реально смешно 🙂
WTF №1 — Проверка лишних свойств
У нас есть тип, который имеет свойства firstName и age, а также функция, которая принимает объект типа Person и просто печатает его:
type Person = { firstName: string, age: number }; function logPerson(person: Person) { console.log(person); }
Чтобы вызвать функцию, мы просто сделаем вот так:
logPerson({ firstName: 'trash', age: 21 });
И это — совершенно ожидаемое поведение. Если мы передадим лишнее поле, то получим ошибку:
logPerson({ firstName: 'trash', age: 21, extraProp: 21 }); // ошибка
Object literal may only specify known properties, and ‘extraProp’ does not exist in type ‘Person’.ts(2353)

Но есть одна интересная деталь: если мы вынесем объект в переменную и передадим её в функцию, ошибки не возникает:
const person = { firstName: 'trash', age: 21, extraProp: 21 }; logPerson(person); // нет ошибки
Мы можем отловить ошибку, если укажем тип объекта явно:
const person: Person = { firstName: 'trash', age: 21, extraProp: 21 // Object literal may only specify known properties, and 'extraProp' does not exist in type 'Person'.ts(2353) };
Но даже в этом случае, если мы очень захотим добавить дополнительное свойство, то можно обойти ограничение:
const person: Person = { firstName: 'trash', age: 21, ...{ extraProp: 21 } // ошибки нет };
WTF №2 — Enums
У нас есть Enum с цветами и функция, которая принимает конкретное значение из этого Enum. Если мы передадим Colors.Green, всё работает. Но если передать строку, совпадающую по значению, то ничего не получится
enum Colors { Green = 'green', Orange = 'orange', Red = 'red', } function isTheBestColor(color: Colors) { // some code } isTheBestColor(Colors.Green); // работает ❤️ isTheBestColor('green'); // не работает 💔
Но…
Если использовать Enum с числовыми значениями:
enum Status { Pending = 0, Declined = 1, Approved = 2, } function validateStatus(status: Status) { // some code } // работает ❤️ validateStatus(Status.Declined); // работает!? 😵💫 validateStatus(1);
Некоторые разработчики предпочитают такую запись, чтобы обойти Enum:
const Foo = { FAILED: 'failed', SUCCESS: 'success', } as const; type Bar = typeof Foo; type BarKeys = keyof Bar; type BarValues = Bar[BarKeys]; const x = (f: BarKeys) => f; x('FAILED'); const y = (f: BarValues) => f; y('failed');
Такая запись позволяет при вызове соответствующей функции сразу выбирать из предзаполненных вариантов и видеть конкретное значение в реальном времени при логировании
WTF №3 — .filter()
Существует популярный способ отфильтровать все falsy-значения с помощью filter
const arr = [1, undefined, 3].filter(Boolean); console.log(arr); // [1, 3]
В этом примере мы ожидаем, что тип arr будет number[], но на самом деле получаем (number | undefined)[], потому что TypeScript не может точнее определить тип возвращаемого значения. Это неудобно: ты точно знаешь, что в рантайме undefined не будет, но в типах обязан это учитывать
WTF №4 — {} vs object vs Object

Существует несколько способов описать объект.
Когда мы хотим создать пустой объект, обычно пишем let foo = {}, но забавно, что мы можем присвоить этой переменной любое примитивное значение — кроме null и undefined. Если же задать тип явно как object, он работает ожидаемо — не принимает примитивы
let foo: object; foo = { hello: 0 }; ✅ foo = []; ✅ foo = false; ❌ foo = null; ❌ foo = undefined; ❌ foo = 42; ❌ foo = 'bar'; ❌
А теперь let foo: {}
foo = { hello: 0 }; ✅ foo = []; ✅ foo = false; ✅ foo = null; ❌ foo = undefined; ❌ foo = 42; ✅ foo = 'bar'; ✅
WTF №5 — Бонусный
У нас есть массив строк и функция, которая принимает массив строк или чисел. Ошибки нет, хотя после изменения тип массива остаётся прежним. WTF?
const foo: string[] = ["1", "2"]; function bar(thing: (number | string)[]) { thing.push(3); } bar(foo); console.log(foo); // ['1', '2', 3]
ссылка на оригинал статьи https://habr.com/ru/articles/927182/
Добавить комментарий