Если вы уже научились азам разработки на TypeScript, но застряли на одном месте и не можете продвинуться дальше, эта статья для вас. Мы подобрали 10 фишек TypeSript для продолжающих изучать язык программирования, которые поднимут скилл на новый уровень.
1. Optional Chaining Optional Chaining (опциональная цепочка) позволяет безопасно получать доступ к вложенным свойствам или методам, не беспокоясь о значениях null или undefined. Он выполняет преждевременную остановку вычислений, если значение любого промежуточного свойства равно null или undefined.
const user = {
name: 'John',
address: {
city: 'New York',
postalCode: '12345'
}
};
const postalCode = user.address?.postalCode;
console.log(postalCode); // Output: 12345
const invalidCode = user.address?.postalCode?.toLowerCase();
console.log(invalidCode); // Output: undefined
2. Nullish Coalescing Operator Nullish Coalescing Operator (оператор объединения нулевого значения) предоставляет переменной новое значение по умолчанию, если её значение равно null или undefined.
const name = null;
const defaultName = name ?? 'Unknown';
console.log(defaultName); // Output: Unknown
const age = 0;
const defaultAge = age ?? 18;
console.log(defaultAge); // Output: 0
3. Type Assertion Type Assertion (утверждение типа) позволяет указать тип переменной, когда TypeScript не может определить его самостоятельно.
const userInput: unknown = 'Hello World';
const strLength = (userInput as string).length;
console.log(strLength); // Output: 11
4. Generics Generics (обобщения) позволяют создавать повторно используемые компоненты, которые могут работать с различными типами данных.
function reverse<T>(items: T[]): T[] {
return items.reverse();
}
const numbers = [1, 2, 3, 4, 5];
const reversedNumbers = reverse(numbers);
console.log(reversedNumbers); // Output: [5, 4, 3, 2, 1]
const strings = ['a', 'b', 'c'];
const reversedStrings = reverse(strings);
console.log(reversedStrings); // Output: ['c', 'b', 'a']
5. keyof Operator Оператор keyof возвращает объединение всех известных имен свойств заданного типа.
interface User {
id: number;
name: string;
email: string;
}
function getUserProperty(user: User, property: keyof User) {
return user[property];
}
const user: User = {
id: 1,
name: 'John Doe',
email: 'john@example.com'
};
const name = getUserProperty(user, 'name');
console.log(name); // Output: John Doe
const invalidProperty = getUserProperty(user, 'age'); // Error: Argument of type '"age"' is not assignable to parameter of type '"id" | "name" | "email"'
6. Type Guards Type Guards (“стражи типа”) позволяют определить тип переменной внутри блока на основе заданного условия.
function logMessage(message: string | number) {
if (typeof message === 'string') {
console.log('Message: ' + message.toUpperCase());
} else {
console.log('Value: ' + message.toFixed(2));
}
}
logMessage('hello'); // Output: Message: HELLO
logMessage(3.14159); // Output: Value: 3.14
7. Intersection Types Типы пересечения позволяют объединять несколько типов в один новый тип, который обладает всеми свойствами и методами объединённых типов.
interface Loggable {
log: () => void;
}
interface Serializable {
serialize: () => string;
}
type Logger = Loggable & Serializable;
class ConsoleLogger implements Loggable {
log() {
console.log('Logging to console...');
}
}
class FileLogger implements Loggable, Serializable {
log() {
console.log('Logging to file...');
}
serialize() {
return 'Serialized log data';
}
}
const logger1: Logger = new ConsoleLogger();
logger1.log(); // Output: Logging to console...
const logger2: Logger = new FileLogger();
logger2.log(); // Output: Logging to file...
console.log(logger2.serialize()); // Output: Serialized log data
8. Mapped Types Отображаемые типы позволяют создавать новые типы из существующих через изменение их свойств.
interface User {
id: number;
name: string;
email: string;
}
type PartialUser = { [K in keyof User]?: User[K] };
const partialUser: PartialUser = {
name: 'John Doe',
email: 'john@example.com'
};
console.log(partialUser); // Output: { name: 'John Doe', email: 'john@example.com' }
9. String Literal Types и Union Types TypeScript поддерживает типы строковых литералов и объединенные типы, которые могут использоваться для определения конкретных значений для переменной.
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
function sendRequest(url: string, method: HttpMethod) {
// send request logic here...
}
sendRequest('/users', 'GET');
sendRequest('/users', 'POST');
sendRequest('/users/1', 'PUT');
sendRequest('/users/1', 'DELETE');
10. Decorators Декораторы позволяют изменять или расширять поведение классов, методов, свойств и других объявлений.
function uppercase(target: any, propertyKey: string) {
let value = target[propertyKey];
const getter = () => value;
const setter = (newValue: string) => {
value = newValue.toUpperCase();
};
Object.defineProperty(target, propertyKey, {
get: getter,
set: setter,
enumerable: true,
configurable: true
});
}
class Person {
@uppercase
name: string;
}
const person = new Person();
person.name = 'John Doe';
console.log(person.name); // Output: JOHN DOE
Заключение Если подборка оказалась полезной, посмотрите и на другие полезные фишки TypeScript в статье «15 продвинутых советов по разработке на TypeScript. Mastering TypeScript: Советы и приемы для эффективного и удобного кода» на английском языке.
Если подборка оказалась слишком сложной, начните с основ и прочтите нашу вводную статью в TypeScript .
А в том случае, если вы не нашли ничего нового в подборке, напишите в комментариях, что действительно нужно изучать TS-разработчикам, чтобы выйти на новый уровень. ?