1.Optional Chaining (?.):
可选链允许您安全地访问嵌套的属性或方法,而无需担心 null 或 undefined 值。如果任何中间属性为 null 或 undefined,它将缩短计算过程。
const user = {
name: 'John',
address: {
city: 'New York',
postalCode: '12345'
}
};
const postalCode = user.address?.postalCode;
console.log(postalCode); // 输出: 12345
const invalidCode = user.address?.postalCode?.toLowerCase();
console.log(invalidCode); // 输出: undefined
2.Nullish Coalescing Operator (??):
nullish 合并运算符在变量为 null 或 undefined 时提供默认值。
const name = null;
const defaultName = name ?? 'Unknown';
console.log(defaultName); // 输出: Unknown
const age = 0;
const defaultAge = age ?? 18;
console.log(defaultAge); // 输出: 0
3.Type Assertion:
类型断言允许您在 TypeScript 无法推断出类型时明确定义变量的类型。
let userInput: unknown
userInput = "Hello World"
const strLength = (userInput as string).length;
console.log(strLength); // 输出: 11
4.Generics:
泛型使您能够创建可与各种类型一起工作的可重用组件。
function reverse<T>(items: T[]): T[] {
return items.reverse();
}
const numbers = [1, 2, 3, 4, 5];
const reversedNumbers = reverse(numbers);
console.log(reversedNumbers); // 输出: [5, 4, 3, 2, 1]
const strings = ['a', 'b', 'c'];
const reversedStrings = reverse(strings);
console.log(reversedStrings); // 输出: ['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); // 输出: John Doe
const invalidProperty = getUserProperty(user, 'age'); // 报错: 类型 '"age"' 的参数不能赋给类型 '"id" | "name" | "email"' 的参数
6.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'); // 输出: Message: HELLO
logMessage(3.14159); // 输出: 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(); // 输出: Logging to console...
const logger2: Logger = new FileLogger();
logger2.log(); // 输出: Logging to file...
console.log(logger2.serialize()); // 输出: 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); // 输出: { name: 'John Doe', email: 'john@example.com' }
使用像这样的 Partial
类型:
type PartialUser = Partial<User>;
const partialUser: PartialUser = {
name: "Nikola Tesla",
email: "nikola@teslaxcorp.com"
};
甚至,添加新的属性,例如:
type MyOwnUser = Partial<User> & { age: number };
const ownUser: MyOwnUser = {
name: "Nikola Tesla",
email: "nikola@teslaxcorp.com",
age: 27
};
9.String Literal Types and Union Types:
TypeScript 支持字符串字面类型和联合类型,可以用来为变量定义特定的值集合。
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
function sendRequest(url: string, method: HttpMethod) {
// 发送请求逻辑在此...
}
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); // 输出: JOHN DOE
11.Index Signatures:
索引签名允许您在接口或类型中定义动态属性名称及其对应的类型。
interface Dictionary {
[key: string]: number;
}
const scores: Dictionary = {
math: 90,
science: 85,
history: 95
};
console.log(scores['math']); // 输出: 90
console.log(scores['english']); // 输出: undefined
12.Type Inference with Conditional Statements:
TypeScript 可以根据条件语句推断出类型,从而使代码更简洁。
function calculateTax(amount: number, isTaxable: boolean) {
if (isTaxable) {
return amount * 1.1; // 类型: number
} else {
return amount; // 类型: number
}
}
const taxableAmount = calculateTax(100, true);
console.log(taxableAmount.toFixed(2)); // 输出: 110.00
const nonTaxableAmount = calculateTax(100, false);
console.log(nonTaxableAmount.toFixed(2)); // 输出: 100.00
13.Readonly Properties:
TypeScript 提供了 readonly
修饰符,用于定义初始化后无法修改的属性。
class Circle {
readonly radius: number;
constructor(radius: number) {
this.radius = radius;
}
getArea() {
return Math.PI * this.radius ** 2;
}
}
const circle = new Circle(5);
console.log(circle.radius); // 输出: 5
// circle.radius = 10; // 报错: 无法分配到 'radius' ,因为它是只读属性
console.log(circle.getArea()); // 输出: 78.53981633974483
14.Type Aliases:
类型别名允许您为现有类型创建自定义名称,提供更语义化的含义并提高代码可读性。
type Point = {
x: number;
y: number;
};
type Shape = 'circle' | 'square' | 'triangle';
function draw(shape: Shape, position: Point) {
console.log(`Drawing a ${shape} at (${position.x}, ${position.y})`);
}
const startPoint: Point = { x: 10, y: 20 };
draw('circle', startPoint); // 输出: Drawing a circle at (10, 20)
15.Type Guards with Classes:
类型保护也可以与类一起使用,以缩小对象实例的类型。
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
}
class Dog extends Animal {
bark() {
console.log('Woof!');
}
}
function makeSound(animal: Animal) {
if (animal instanceof Dog) {
animal.bark(); // 类型: Dog
} else {
console.log('Unknown animal');
}
}
const dog = new Dog('Buddy');
const animal = new Animal('Unknown');
makeSound(dog); // 输出: Woof!
makeSound(animal); // 输出: Unknown animal
16. const assertion
// Type '"hello"'
let x = "hello" as const;
// Type 'readonly [10, 20]'
let y = [10, 20] as const;
// Type '{ readonly text: "hello" }'
let z = { text: "hello" } as const;