一文看懂--什么是typescript
/**
- ========================================
- TypeScript 完整教程:从入门到精通
- ========================================
- 目录:
-
- TypeScript 基础
-
- 基本类型
-
- 接口 (Interface)
-
- 类 (Class)
-
- 函数
-
- 泛型 (Generics)
-
- 高级类型
-
- 类型守卫和类型断言
-
- 装饰器 (Decorators)
-
- 模块和命名空间
-
- 实战项目示例
*/
- 实战项目示例
// ========================================
// 1. TypeScript 基础
// ========================================
/**
- TypeScript 是 JavaScript 的超集,添加了静态类型系统
- 编译后生成纯 JavaScript 代码
*/
// 变量声明
let message: string = "Hello TypeScript";
let count: number = 42;
let isActive: boolean = true;
// 类型推断 - TypeScript 可以自动推断类型
let inferredString = "这是字符串"; // 自动推断为 string
let inferredNumber = 100; // 自动推断为 number
// ========================================
// 2. 基本类型
// ========================================
// 2.1 基础类型
let str: string = "文本";
let num: number = 123;
let bool: boolean = false;
let u: undefined = undefined;
let n: null = null;
// 2.2 数组类型
let arr1: number[] = [1, 2, 3];
let arr2: Array
let arr3: (string | number)[] = [1, "2", 3]; // 联合类型数组
// 2.3 元组 (Tuple) - 固定长度和类型的数组
let tuple: [string, number, boolean] = ["hello", 42, true];
console.log(tuple[0]); // "hello"
// 2.4 枚举 (Enum)
enum Color {
Red, // 0
Green, // 1
Blue // 2
}
let c: Color = Color.Green;
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT"
}
// 2.5 Any 类型 - 关闭类型检查
let anything: any = 42;
anything = "字符串";
anything = true;
// 2.6 Unknown 类型 - 更安全的 any
let uncertain: unknown = 4;
// uncertain.toFixed(); // 错误:必须先进行类型检查
if (typeof uncertain === "number") {
uncertain.toFixed(2); // 正确
}
// 2.7 Void 类型 - 通常用于函数无返回值
function logMessage(msg: string): void {
console.log(msg);
}
// 2.8 Never 类型 - 永远不会返回
function throwError(message: string): never {
throw new Error(message);
}
// 2.9 Object 类型
let obj: object = { name: "张三" };
let specificObj: { name: string; age: number } = {
name: "李四",
age: 25
};
// ========================================
// 3. 接口 (Interface)
// ========================================
// 3.1 基本接口
interface User {
id: number;
name: string;
email: string;
}
const user1: User = {
id: 1,
name: "张三",
email: "zhangsan@example.com"
};
// 3.2 可选属性
interface Product {
id: number;
name: string;
description?: string; // 可选属性
price: number;
}
// 3.3 只读属性
interface Point {
readonly x: number;
readonly y: number;
}
let p1: Point = { x: 10, y: 20 };
// p1.x = 5; // 错误:只读属性
// 3.4 函数类型接口
interface SearchFunc {
(source: string, subString: string): boolean;
}
const mySearch: SearchFunc = (src, sub) => {
return src.includes(sub);
};
// 3.5 索引签名
interface StringArray {
[index: number]: string;
}
let myArray: StringArray = ["Bob", "Alice"];
interface Dictionary {
[key: string]: number;
}
let scores: Dictionary = {
math: 95,
english: 88
};
// 3.6 接口继承
interface Shape {
color: string;
}
interface Square extends Shape {
sideLength: number;
}
let square: Square = {
color: "blue",
sideLength: 10
};
// 3.7 混合类型接口
interface Counter {
(start: number): string;
interval: number;
reset(): void;
}
function getCounter(): Counter {
let counter = function(start: number) {
return Started at ${start};
} as Counter;
counter.interval = 123;
counter.reset = function() {
console.log("Reset");
};
return counter;
}
// ========================================
// 4. 类 (Class)
// ========================================
// 4.1 基本类
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
move(distance: number = 0): void {
console.log(${this.name} 移动了 ${distance} 米);
}
}
const dog = new Animal("旺财");
dog.move(10);
// 4.2 继承
class Dog extends Animal {
breed: string;
constructor(name: string, breed: string) {
super(name); // 调用父类构造函数
this.breed = breed;
}
bark(): void {
console.log("汪汪汪!");
}
// 重写父类方法
move(distance: number = 5): void {
console.log("跑步中...");
super.move(distance);
}
}
// 4.3 访问修饰符
class Person {
public name: string; // 公共属性(默认)
private age: number; // 私有属性
protected gender: string; // 受保护属性
readonly id: number; // 只读属性
constructor(name: string, age: number, gender: string, id: number) {
this.name = name;
this.age = age;
this.gender = gender;
this.id = id;
}
public getAge(): number {
return this.age;
}
private calculateBirthYear(): number {
return new Date().getFullYear() - this.age;
}
}
// 4.4 Getter 和 Setter
class Employee {
private _salary: number = 0;
get salary(): number {
return this._salary;
}
set salary(value: number) {
if (value < 0) {
throw new Error("薪资不能为负数");
}
this._salary = value;
}
}
// 4.5 静态成员
class MathUtil {
static PI: number = 3.14159;
static calculateCircleArea(radius: number): number {
return this.PI * radius * radius;
}
}
console.log(MathUtil.PI);
console.log(MathUtil.calculateCircleArea(5));
// 4.6 抽象类
abstract class Department {
abstract name: string;
constructor(public departmentId: number) {}
abstract printMeeting(): void;
printName(): void {
console.log(部门: ${this.name});
}
}
class AccountingDepartment extends Department {
name: string = "会计部";
printMeeting(): void {
console.log("会计部门会议在早上 10 点");
}
}
// ========================================
// 5. 函数
// ========================================
// 5.1 函数类型
function add(x: number, y: number): number {
return x + y;
}
// 5.2 可选参数和默认参数
function buildName(firstName: string, lastName?: string): string {
if (lastName) {
return ${firstName} ${lastName};
}
return firstName;
}
function greet(name: string, greeting: string = "你好"): string {
return ${greeting}, ${name}!;
}
// 5.3 剩余参数
function sum(...numbers: number[]): number {
return numbers.reduce((acc, curr) => acc + curr, 0);
}
console.log(sum(1, 2, 3, 4, 5)); // 15
// 5.4 函数重载
function reverse(x: string): string;
function reverse(x: number): number;
function reverse(x: string | number): string | number {
if (typeof x === "string") {
return x.split("").reverse().join("");
}
return Number(x.toString().split("").reverse().join(""));
}
console.log(reverse("hello")); // "olleh"
console.log(reverse(12345)); // 54321
// 5.5 箭头函数
const multiply = (a: number, b: number): number => a * b;
// 5.6 this 参数
interface Card {
suit: string;
card: number;
}
interface Deck {
suits: string[];
cards: number[];
createCardPicker(this: Deck): () => Card;
}
const deck: Deck = {
suits: ["红心", "方块", "梅花", "黑桃"],
cards: Array(52).fill(0).map((_, i) => i),
createCardPicker: function(this: Deck) {
return () => {
const pickedCard = Math.floor(Math.random() * 52);
const pickedSuit = Math.floor(pickedCard / 13);
return {
suit: this.suits[pickedSuit],
card: pickedCard % 13
};
};
}
};
// ========================================
// 6. 泛型 (Generics)
// ========================================
// 6.1 泛型函数
function identity
return arg;
}
let output1 = identity
let output2 = identity
let output3 = identity("自动推断"); // 类型推断
// 6.2 泛型数组
function loggingIdentity
console.log(arg.length);
return arg;
}
// 6.3 泛型接口
interface GenericIdentityFn
(arg: T): T;
}
let myIdentity: GenericIdentityFn
// 6.4 泛型类
class GenericNumber
zeroValue: T;
add: (x: T, y: T) => T;
constructor(zeroValue: T, addFn: (x: T, y: T) => T) {
this.zeroValue = zeroValue;
this.add = addFn;
}
}
let myGenericNumber = new GenericNumber
// 6.5 泛型约束
interface Lengthwise {
length: number;
}
function logLength
console.log(arg.length);
return arg;
}
logLength("hello"); // 正确
logLength([1, 2, 3]); // 正确
// logLength(123); // 错误:number 没有 length 属性
// 6.6 在泛型约束中使用类型参数
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
let person = { name: "张三", age: 30 };
let personName = getProperty(person, "name"); // 正确
// let invalid = getProperty(person, "unknown"); // 错误
// 6.7 泛型工具类型
interface Todo {
title: string;
description: string;
completed: boolean;
}
// Partial - 所有属性变为可选
type PartialTodo = Partial
// Required - 所有属性变为必选
type RequiredTodo = Required
// Readonly - 所有属性变为只读
type ReadonlyTodo = Readonly
// Pick - 选择部分属性
type TodoPreview = Pick<Todo, "title" | "completed">;
// Omit - 排除部分属性
type TodoWithoutDescription = Omit<Todo, "description">;
// Record - 构造对象类型
type PageInfo = Record<"home" | "about" | "contact", { title: string }>;
// ========================================
// 7. 高级类型
// ========================================
// 7.1 联合类型
type StringOrNumber = string | number;
function printId(id: StringOrNumber): void {
console.log(ID: ${id});
}
// 7.2 交叉类型
interface Colorful {
color: string;
}
interface Circle {
radius: number;
}
type ColorfulCircle = Colorful & Circle;
const cc: ColorfulCircle = {
color: "红色",
radius: 10
};
// 7.3 类型别名
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
// 7.4 字面量类型
type Direction2 = "north" | "south" | "east" | "west";
function move2(direction: Direction2): void {
console.log(向 ${direction} 移动);
}
// 7.5 类型索引
interface PersonInfo {
name: string;
age: number;
location: string;
}
type PersonKeys = keyof PersonInfo; // "name" | "age" | "location"
// 7.6 映射类型
type Nullable
[P in keyof T]: T[P] | null;
};
type NullablePerson = Nullable
// 7.7 条件类型
type IsString
type A = IsString
type B = IsString
// 7.8 infer 关键字
type ReturnType2
function getUser() {
return { name: "张三", age: 25 };
}
type UserReturnType = ReturnType2
// ========================================
// 8. 类型守卫和类型断言
// ========================================
// 8.1 typeof 类型守卫
function padLeft(value: string, padding: string | number): string {
if (typeof padding === "number") {
return " ".repeat(padding) + value;
}
return padding + value;
}
// 8.2 instanceof 类型守卫
class Bird {
fly(): void {
console.log("鸟在飞");
}
}
class Fish {
swim(): void {
console.log("鱼在游");
}
}
function move3(animal: Bird | Fish): void {
if (animal instanceof Bird) {
animal.fly();
} else {
animal.swim();
}
}
// 8.3 自定义类型守卫
interface Cat {
meow(): void;
}
interface Dog2 {
bark(): void;
}
function isCat(pet: Cat | Dog2): pet is Cat {
return (pet as Cat).meow !== undefined;
}
function makeSound(pet: Cat | Dog2): void {
if (isCat(pet)) {
pet.meow();
} else {
pet.bark();
}
}
// 8.4 类型断言
let someValue: unknown = "这是一个字符串";
let strLength1: number = (someValue as string).length;
let strLength2: number = (
// 8.5 非空断言
function processValue(value: string | null): void {
console.log(value!.toUpperCase()); // 断言 value 不为 null
}
// 8.6 as const 断言
const config = {
host: "localhost",
port: 8080
} as const; // 所有属性变为只读字面量类型
// ========================================
// 9. 装饰器 (Decorators)
// ========================================
// 注意:需要在 tsconfig.json 中启用 experimentalDecorators
// 9.1 类装饰器
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};
}
}
// 9.2 方法装饰器
function enumerable(value: boolean) {
return function (
target: any,
propertyKey: string,
descriptor: PropertyDescriptor
) {
descriptor.enumerable = value;
};
}
class Calculator {
@enumerable(false)
calculate(x: number, y: number): number {
return x + y;
}
}
// 9.3 属性装饰器
function format(formatString: string) {
return function (target: any, propertyKey: string) {
let value: string;
const getter = function() {
return value;
};
const setter = function(newVal: string) {
value = formatString.replace("{value}", newVal);
};
Object.defineProperty(target, propertyKey, {
get: getter,
set: setter,
enumerable: true,
configurable: true
});
};
}
class FormattedGreeting {
@format("Hello, {value}!")
greeting: string;
}
// ========================================
// 10. 模块和命名空间
// ========================================
// 10.1 模块导出
// export const PI = 3.14;
// export function calculateArea(radius: number): number {
// return PI * radius * radius;
// }
// export default class Circle {
// constructor(public radius: number) {}
// }
// 10.2 模块导入
// import Circle, { PI, calculateArea } from './circle';
// import * as MathLib from './mathLib';
// 10.3 命名空间
namespace Validation {
export interface StringValidator {
isValid(s: string): boolean;
}
export class EmailValidator implements StringValidator {
isValid(s: string): boolean {
const emailRegex = /[\s@]+@[\s@]+.[\s@]+$/;
return emailRegex.test(s);
}
}
export class PhoneValidator implements StringValidator {
isValid(s: string): boolean {
const phoneRegex = /^\d{11}$/;
return phoneRegex.test(s);
}
}
}
const emailValidator = new Validation.EmailValidator();
console.log(emailValidator.isValid("test@example.com")); // true
// ========================================
// 11. 实战项目示例
// ========================================
// 11.1 用户管理系统
interface IUser {
id: number;
username: string;
email: string;
role: "admin" | "user" | "guest";
createdAt: Date;
}
interface IUserRepository {
create(user: Omit<IUser, "id" | "createdAt">): IUser;
findById(id: number): IUser | undefined;
findAll(): IUser[];
update(id: number, user: Partial
delete(id: number): boolean;
}
class UserRepository implements IUserRepository {
private users: IUser[] = [];
private nextId: number = 1;
create(userData: Omit<IUser, "id" | "createdAt">): IUser {
const newUser: IUser = {
id: this.nextId++,
...userData,
createdAt: new Date()
};
this.users.push(newUser);
return newUser;
}
findById(id: number): IUser | undefined {
return this.users.find(user => user.id === id);
}
findAll(): IUser[] {
return [...this.users];
}
update(id: number, userData: Partial
const userIndex = this.users.findIndex(user => user.id === id);
if (userIndex === -1) return undefined;
this.users[userIndex] = {
...this.users[userIndex],
...userData
};
return this.users[userIndex];
}
delete(id: number): boolean {
const userIndex = this.users.findIndex(user => user.id === id);
if (userIndex === -1) return false;
this.users.splice(userIndex, 1);
return true;
}
}
// 11.2 API 响应类型
interface ApiResponse
success: boolean;
data?: T;
error?: string;
timestamp: number;
}
class ApiClient {
async fetchData
try {
// 模拟 API 请求
const data = {} as T;
return {
success: true,
data,
timestamp: Date.now()
};
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : "未知错误",
timestamp: Date.now()
};
}
}
}
// 11.3 事件发射器
type EventCallback<T = any> = (data: T) => void;
class EventEmitter {
private events: Map<string, EventCallback[]> = new Map();
on(event: string, callback: EventCallback): void {
if (!this.events.has(event)) {
this.events.set(event, []);
}
this.events.get(event)!.push(callback);
}
off(event: string, callback: EventCallback): void {
const callbacks = this.events.get(event);
if (callbacks) {
const index = callbacks.indexOf(callback);
if (index > -1) {
callbacks.splice(index, 1);
}
}
}
emit
const callbacks = this.events.get(event);
if (callbacks) {
callbacks.forEach(callback => callback(data));
}
}
}
// 11.4 状态管理
interface State {
count: number;
user: IUser | null;
loading: boolean;
}
type Action =
| { type: "INCREMENT" }
| { type: "DECREMENT" }
| { type: "SET_USER"; payload: IUser }
| { type: "SET_LOADING"; payload: boolean };
class Store {
private state: State = {
count: 0,
user: null,
loading: false
};
private listeners: Array<(state: State) => void> = [];
getState(): Readonly
return { ...this.state };
}
dispatch(action: Action): void {
this.state = this.reducer(this.state, action);
this.notify();
}
subscribe(listener: (state: State) => void): () => void {
this.listeners.push(listener);
return () => {
const index = this.listeners.indexOf(listener);
if (index > -1) {
this.listeners.splice(index, 1);
}
};
}
private reducer(state: State, action: Action): State {
switch (action.type) {
case "INCREMENT":
return { ...state, count: state.count + 1 };
case "DECREMENT":
return { ...state, count: state.count - 1 };
case "SET_USER":
return { ...state, user: action.payload };
case "SET_LOADING":
return { ...state, loading: action.payload };
default:
return state;
}
}
private notify(): void {
this.listeners.forEach(listener => listener(this.getState()));
}
}
// 使用示例
const userRepo = new UserRepository();
const user1Example = userRepo.create({
username: "zhangsan",
email: "zhangsan@example.com",
role: "user"
});
console.log("创建的用户:", user1Example);
const store = new Store();
const unsubscribe = store.subscribe((state) => {
console.log("状态更新:", state);
});
store.dispatch({ type: "INCREMENT" });
store.dispatch({ type: "SET_USER", payload: user1Example });
/**
- ========================================
- 总结与最佳实践
- ========================================
-
- 始终启用严格模式 (strict: true)
-
- 优先使用 interface 而不是 type(除非需要联合类型)
-
- 避免使用 any,使用 unknown 替代
-
- 善用类型推断,减少冗余类型注解
-
- 使用 readonly 保护不可变数据
-
- 合理使用泛型提高代码复用性
-
- 利用工具类型简化类型操作
-
- 使用类型守卫确保运行时类型安全
-
- 模块化组织代码,避免命名冲突
-
- 编写清晰的类型文档和注释
*/
- 编写清晰的类型文档和注释
// 导出示例
export {
UserRepository,
ApiClient,
EventEmitter,
Store
};

浙公网安备 33010602011771号