TypeScript 进阶教程
高级类型
交叉类型(Intersection Types)
交叉类型将多个类型合并为一个类型。它允许你将不同类型的属性合并到一个对象中。
typescript
复制代码
interface Person { name: string; } interface Contact { phone: string; } type Employee = Person & Contact; let employee: Employee = { name: "John Doe", phone: "123-456-7890" };
联合类型(Union Types)
联合类型允许一个变量可以是多种类型之一。它用于描述一个值可以是几种类型之一。
typescript
复制代码
function printId(id: number | string) { console.log("Your ID is: " + id); } printId(101); printId("202");
类型守卫(Type Guards)
类型守卫用于在运行时检查一个值的类型。它们常用于联合类型的条件检查。
typescript
复制代码
function isString(value: any): value is string { return typeof value === "string"; } function example(value: number | string) { if (isString(value)) { console.log(value.toUpperCase()); // 在这里 value 是 string } else { console.log(value.toFixed(2)); // 在这里 value 是 number } }
类型操作
类型别名(Type Aliases)
类型别名用于为一个类型起一个新的名字。
typescript
复制代码
type StringOrNumber = string | number; let value: StringOrNumber = "Hello"; value = 42;
类型断言(Type Assertions)
类型断言用于告诉编译器某个值的具体类型。
typescript
复制代码
let someValue: any = "this is a string"; let strLength: number = (someValue as string).length;
索引类型(Index Types)
索引类型用于检查对象的动态属性。
typescript
复制代码
function pluck<T, K extends keyof T>(obj: T, keys: K[]): T[K][] { return keys.map(key => obj[key]); } let person = { name: "John", age: 30, city: "New York" }; let personName = pluck(person, ["name"]); // 返回 ["John"]
映射类型(Mapped Types)
映射类型基于旧类型创建新类型。
typescript
复制代码
type Readonly<T> = { readonly [P in keyof T]: T[P]; }; type Partial<T> = { [P in keyof T]?: T[P]; }; interface Person { name: string; age: number; } let readonlyPerson: Readonly<Person> = { name: "John", age: 30 }; // readonlyPerson.name = "Jane"; // Error: Cannot assign to 'name' because it is a read-only property
泛型(Generics)
泛型使得组件可以支持多种类型的数据。这样用户可以用自己的数据类型来定义组件。
typescript
复制代码
function identity<T>(arg: T): T { return arg; } let output1 = identity<string>("myString"); let output2 = identity<number>(42);
泛型接口和类
typescript
复制代码
interface GenericIdentityFn<T> { (arg: T): T; } function identity<T>(arg: T): T { return arg; } let myIdentity: GenericIdentityFn<number> = identity; class GenericNumber<T> { zeroValue: T; add: (x: T, y: T) => T; } let myGenericNumber = new GenericNumber<number>(); myGenericNumber.zeroValue = 0; myGenericNumber.add = function(x, y) { return x + y; };
高级类特性
抽象类(Abstract Classes)
抽象类是不能被实例化的类,它们只能被继承。
typescript
复制代码
abstract class Animal { abstract makeSound(): void; move(): void { console.log("Moving..."); } } class Dog extends Animal { makeSound() { console.log("Woof! Woof!"); } } let dog = new Dog(); dog.makeSound(); dog.move();
类装饰器(Class Decorators)
装饰器是用于修改类及其成员行为的特殊类型的声明。
typescript
复制代码
function sealed(constructor: Function) { Object.seal(constructor); Object.seal(constructor.prototype); } @sealed class Greeter { greeting: string; constructor(message: string) { this.greeting = message; } greet() { return "Hello, " + this.greeting; } }
模块和命名空间
模块(Modules)
TypeScript 使用 ES6 模块语法。
typescript
复制代码
// math.ts export function add(x: number, y: number): number { return x + y; } // main.ts import { add } from './math'; console.log(add(5, 3));
命名空间(Namespaces)
命名空间用于组织代码,并避免命名冲突。
typescript
复制代码
namespace Validation { export interface StringValidator { isAcceptable(s: string): boolean; } const lettersRegexp = /^[A-Za-z]+$/; export class LettersOnlyValidator implements StringValidator { isAcceptable(s: string) { return lettersRegexp.test(s); } } } let validator = new Validation.LettersOnlyValidator(); console.log(validator.isAcceptable("Hello")); // true
类型声明(Type Declarations)
TypeScript 可以与 JavaScript 库一起使用。你可以使用类型声明文件(.d.ts)来描述库的 API。
typescript
复制代码
// lodash.d.ts declare module "lodash" { export function chunk<T>(array: T[], size: number): T[][]; } // main.ts import { chunk } from "lodash"; console.log(chunk([1, 2, 3, 4, 5], 2)); // [[1, 2], [3, 4], [5]]
高级类型声明
条件类型(Conditional Types)
条件类型根据条件选择一种类型。
typescript
复制代码
type TypeName<T> = T extends string ? "string" : T extends number ? "number" : T extends boolean ? "boolean" : T extends undefined ? "undefined" : T extends Function ? "function" : "object"; type T1 = TypeName<string>; // "string" type T2 = TypeName<"a">; // "string" type T3 = TypeName<true>; // "boolean" type T4 = TypeName<() => void>; // "function" type T5 = TypeName<{}>; // "object"
类型推断(Type Inference)
TypeScript 能够根据上下文自动推断类型。
typescript
复制代码
let x = 3; // TypeScript 推断 x 的类型为 number
模块分割和动态导入
你可以使用动态导入语法来按需加载模块。
typescript
复制代码
// math.ts export function add(x: number, y: number): number { return x + y; } // main.ts async function loadMath() { const math = await import('./math'); console.log(math.add(5, 3)); } loadMath();
Mixins(混合)
Mixins 是一种实现多继承的模式,TypeScript 支持通过类和接口实现 Mixins。
typescript
复制代码
class Disposable { isDisposed: boolean = false; dispose() { this.isDisposed = true; } } class Activatable { isActive: boolean = false; activate() { this.isActive = true; } deactivate() { this.isActive = false; } } class SmartObject implements Disposable, Activatable { isDisposed: boolean = false; dispose: () => void; isActive: boolean = false; activate: () => void; deactivate: () => void; constructor() { setInterval(() => console.log(this.isActive + " : " + this.isDisposed), 500); } } applyMixins(SmartObject, [Disposable, Activatable]); let smartObj = new SmartObject(); setTimeout(() => smartObj.activate(), 1000); function applyMixins(derivedCtor: any, baseCtors: any[]) { baseCtors.forEach(baseCtor => { Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => { derivedCtor.prototype[name] = baseCtor.prototype[name]; }); }); }
进阶工具类型
TypeScript 提供了一些内置工具类型,用于常见的类型转换。
typescript
复制代码
type Partial<T> = { [P in keyof T]?: T[P]; }; type Readonly<T> = { readonly [P in keyof T]: T[P]; }; type Pick<T, K extends keyof T> = { [P in K]: T[P]; }; type Record<K extends keyof any, T> = { [P in K]: T; };
这是一个 TypeScript 的进阶教程,涵盖了许多高级特性和用法。通过学习这些内容,你可以更好地利用 TypeScript 提高代码质量和开发效率。希望对你有所帮助!