TypeScript 基础知识
一、TypeScript 概述
1.1 什么是 TypeScript
TypeScript 是 JavaScript 的超集,添加了静态类型系统,编译后生成纯 JavaScript 代码。
核心特点:
- 静态类型检查
- 编译时错误检测
- 更好的 IDE 支持
- 渐进式采用
- 兼容 JavaScript
1.2 为什么使用 TypeScript
| 优势 | 说明 |
|---|---|
| 类型安全 | 编译时发现错误,减少运行时问题 |
| 代码提示 | IDE 智能提示,提升开发效率 |
| 重构安全 | 类型系统保证重构的正确性 |
| 文档作用 | 类型即文档,代码更易理解 |
| 团队协作 | 类型约束减少沟通成本 |
1.3 安装和使用
# 全局安装
npm install -g typescript
# 本地安装
npm install --save-dev typescript
# 编译 TypeScript
tsc index.ts
# 监听模式
tsc --watch index.ts
# 初始化 tsconfig.json
tsc --init
二、基础类型
2.1 基本类型
// 布尔值
let isDone: boolean = false;
// 数字
let count: number = 10;
let price: number = 99.99;
// 字符串
let name: string = "zhangsan";
let message: string = `Hello, ${name}`;
// 数组
let list: number[] = [1, 2, 3];
let list2: Array<number> = [1, 2, 3];
// 元组
let tuple: [string, number] = ["hello", 10];
// 枚举
enum Color {
Red,
Green,
Blue
}
let color: Color = Color.Red;
// Any(任意类型)
let notSure: any = 4;
notSure = "maybe a string";
notSure = false;
// Void(无类型)
function warnUser(): void {
console.log("This is a warning");
}
// Null 和 Undefined
let u: undefined = undefined;
let n: null = null;
// Never(永不存在的值)
function error(message: string): never {
throw new Error(message);
}
// Object(非原始类型)
let obj: object = { name: "zhangsan" };
2.2 类型推断
// TypeScript 会自动推断类型
let x = 3; // x 的类型是 number
let y = "hello"; // y 的类型是 string
let z = [1, 2, 3]; // z 的类型是 number[]
// 明确指定类型
let x: number = 3;
2.3 类型断言
// 方式1:尖括号语法
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
// 方式2:as 语法(推荐)
let strLength2: number = (someValue as string).length;
// 非空断言
let element: HTMLElement | null = document.getElementById("myId");
element!.style.color = "red"; // 使用 ! 断言非空
三、接口(Interface)
3.1 基础接口
// 定义接口
interface User {
name: string;
age: number;
}
// 使用接口
function greet(user: User): string {
return `Hello, ${user.name}`;
}
let user: User = {
name: "zhangsan",
age: 25
};
3.2 可选属性
interface User {
name: string;
age?: number; // 可选属性
email?: string;
}
let user1: User = { name: "zhangsan" };
let user2: User = { name: "lisi", age: 30 };
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;
}
let mySearch: SearchFunc = function(src: string, sub: string): boolean {
return src.search(sub) > -1;
};
3.5 索引签名
interface StringArray {
[index: number]: string;
}
let myArray: StringArray = ["Bob", "Fred"];
let myStr: string = myArray[0];
3.6 接口继承
interface Shape {
color: string;
}
interface Square extends Shape {
sideLength: number;
}
let square: Square = {
color: "blue",
sideLength: 10
};
四、类型别名(Type)
4.1 基础用法
// 类型别名
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
if (typeof n === "string") {
return n;
} else {
return n();
}
}
4.2 联合类型
type Status = "pending" | "success" | "error";
let currentStatus: Status = "pending";
4.3 交叉类型
type Person = {
name: string;
age: number;
};
type Employee = {
employeeId: string;
department: string;
};
type EmployeePerson = Person & Employee;
let employee: EmployeePerson = {
name: "zhangsan",
age: 25,
employeeId: "E001",
department: "IT"
};
4.4 Interface vs Type
| 特性 | Interface | Type |
|---|---|---|
| 扩展 | 使用 extends | 使用 & |
| 合并 | 可以声明合并 | 不能合并 |
| 联合类型 | 不支持 | 支持 |
| 交叉类型 | 支持 | 支持 |
| 适用场景 | 对象形状 | 类型别名、联合类型 |
五、函数
5.1 函数类型
// 函数声明
function add(x: number, y: number): number {
return x + y;
}
// 函数表达式
let myAdd = function(x: number, y: number): number {
return x + y;
};
// 箭头函数
let myAdd2 = (x: number, y: number): number => x + y;
5.2 可选参数和默认参数
function buildName(firstName: string, lastName?: string): string {
if (lastName) {
return firstName + " " + lastName;
} else {
return firstName;
}
}
function buildName2(firstName: string, lastName: string = "Smith"): string {
return firstName + " " + lastName;
}
5.3 剩余参数
function buildName3(firstName: string, ...restOfName: string[]): string {
return firstName + " " + restOfName.join(" ");
}
let employeeName = buildName3("Joseph", "Samuel", "Lucas", "MacKinzie");
5.4 函数重载
function pickCard(x: { suit: string; card: number }[]): number;
function pickCard(x: number): { suit: string; card: number };
function pickCard(x: any): any {
if (typeof x == "object") {
return Math.floor(Math.random() * x.length);
} else if (typeof x == "number") {
let pickedSuit = Math.floor(x / 13);
return { suit: suits[pickedSuit], card: x % 13 };
}
}
六、类(Class)
6.1 基础类
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet(): string {
return "Hello, " + this.greeting;
}
}
let greeter = new Greeter("world");
6.2 继承
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
move(distance: number = 0): void {
console.log(`${this.name} moved ${distance}m.`);
}
}
class Dog extends Animal {
constructor(name: string) {
super(name);
}
move(distance: number = 5): void {
console.log("Running...");
super.move(distance);
}
}
6.3 访问修饰符
class Person {
public name: string; // 公共,默认
private age: number; // 私有
protected email: string; // 受保护
constructor(name: string, age: number, email: string) {
this.name = name;
this.age = age;
this.email = email;
}
}
6.4 只读属性
class Octopus {
readonly name: string;
readonly numberOfLegs: number = 8;
constructor(name: string) {
this.name = name;
}
}
6.5 抽象类
abstract class Animal {
abstract makeSound(): void;
move(): void {
console.log("roaming the earth...");
}
}
class Dog extends Animal {
makeSound(): void {
console.log("Woof! Woof!");
}
}
6.6 静态属性
class Grid {
static origin = { x: 0, y: 0 };
static calculateDistance(point1: { x: number; y: number }, point2: { x: number; y: number }): number {
let xDist = point1.x - point2.x;
let yDist = point1.y - point2.y;
return Math.sqrt(xDist * xDist + yDist * yDist);
}
}
console.log(Grid.origin);
let distance = Grid.calculateDistance({ x: 0, y: 0 }, { x: 3, y: 4 });
七、泛型(Generics)
7.1 基础泛型
// 泛型函数
function identity<T>(arg: T): T {
return arg;
}
let output = identity<string>("myString");
let output2 = identity<number>(123);
// 类型推断
let output3 = identity("myString"); // 自动推断为 string
7.2 泛型接口
interface GenericIdentityFn<T> {
(arg: T): T;
}
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: GenericIdentityFn<number> = identity;
7.3 泛型类
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; };
7.4 泛型约束
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}
loggingIdentity({ length: 10, value: 3 });
7.5 在泛型约束中使用类型参数
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
let x = { a: 1, b: 2, c: 3, d: 4 };
getProperty(x, "a"); // 正确
// getProperty(x, "m"); // 错误
八、高级类型
8.1 联合类型
function padLeft(value: string, padding: string | number): string {
if (typeof padding === "number") {
return Array(padding + 1).join(" ") + value;
}
if (typeof padding === "string") {
return padding + value;
}
throw new Error(`Expected string or number, got '${padding}'.`);
}
8.2 交叉类型
function extend<T, U>(first: T, second: U): T & U {
let result = <T & U>{};
for (let id in first) {
(<any>result)[id] = (<any>first)[id];
}
for (let id in second) {
if (!result.hasOwnProperty(id)) {
(<any>result)[id] = (<any>second)[id];
}
}
return result;
}
8.3 类型保护
// typeof 类型保护
function isString(x: any): x is string {
return typeof x === "string";
}
// instanceof 类型保护
class Bird {
fly() {
console.log("flying");
}
}
class Fish {
swim() {
console.log("swimming");
}
}
function getSmallPet(): Fish | Bird {
// ...
}
let pet = getSmallPet();
if (pet instanceof Bird) {
pet.fly();
} else {
pet.swim();
}
8.4 索引类型
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
let x = { a: 1, b: 2, c: 3, d: 4 };
let a = getProperty(x, "a");
8.5 映射类型
// Readonly
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
// Partial
type Partial<T> = {
[P in keyof T]?: T[P];
};
// Pick
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
// Record
type Record<K extends keyof any, T> = {
[P in K]: T;
};
九、模块
9.1 导出
// 命名导出
export const name = "zhangsan";
export function greet() {
return "Hello";
}
export class User {
name: string;
}
// 默认导出
export default class User {
name: string;
}
// 重新导出
export { User } from "./User";
export * from "./User";
9.2 导入
// 命名导入
import { name, greet, User } from "./module";
// 默认导入
import User from "./User";
// 重命名导入
import { User as MyUser } from "./User";
// 导入所有
import * as utils from "./utils";
十、命名空间
10.1 基础用法
namespace Validation {
export interface StringValidator {
isAcceptable(s: string): boolean;
}
const lettersRegexp = /^[A-Za-z]+$/;
const numberRegexp = /^[0-9]+$/;
export class LettersOnlyValidator implements StringValidator {
isAcceptable(s: string) {
return lettersRegexp.test(s);
}
}
export class ZipCodeValidator implements StringValidator {
isAcceptable(s: string) {
return s.length === 5 && numberRegexp.test(s);
}
}
}
10.2 多文件命名空间
// Validation.ts
namespace Validation {
export interface StringValidator {
isAcceptable(s: string): boolean;
}
}
// LettersOnlyValidator.ts
/// <reference path="Validation.ts" />
namespace Validation {
const lettersRegexp = /^[A-Za-z]+$/;
export class LettersOnlyValidator implements StringValidator {
isAcceptable(s: string) {
return lettersRegexp.test(s);
}
}
}
十一、装饰器(Decorators)
11.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;
}
}
11.2 方法装饰器
function enumerable(value: boolean) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
descriptor.enumerable = value;
};
}
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
@enumerable(false)
greet() {
return "Hello, " + this.greeting;
}
}
11.3 属性装饰器
function format(formatString: string) {
return function (target: any, propertyKey: string) {
// ...
};
}
class Greeter {
@format("Hello, %s")
greeting: string;
}
十二、工具类型
12.1 Partial
interface User {
name: string;
age: number;
email: string;
}
type PartialUser = Partial<User>;
// { name?: string; age?: number; email?: string; }
12.2 Required
interface User {
name?: string;
age?: number;
}
type RequiredUser = Required<User>;
// { name: string; age: number; }
12.3 Readonly
interface User {
name: string;
age: number;
}
type ReadonlyUser = Readonly<User>;
// { readonly name: string; readonly age: number; }
12.4 Pick
interface User {
name: string;
age: number;
email: string;
}
type UserBasic = Pick<User, "name" | "age">;
// { name: string; age: number; }
12.5 Omit
interface User {
name: string;
age: number;
email: string;
}
type UserWithoutEmail = Omit<User, "email">;
// { name: string; age: number; }
12.6 Record
type PageInfo = {
title: string;
};
type Page = "home" | "about" | "contact";
const x: Record<Page, PageInfo> = {
home: { title: "Home" },
about: { title: "About" },
contact: { title: "Contact" }
};
十三、配置文件
13.1 tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020", "DOM"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
13.2 常用配置选项
| 选项 | 说明 |
|---|---|
| target | 编译目标版本(ES5/ES2020等) |
| module | 模块系统(commonjs/esnext等) |
| lib | 包含的类型库 |
| strict | 启用所有严格类型检查 |
| noImplicitAny | 禁止隐式 any |
| strictNullChecks | 严格空值检查 |
| esModuleInterop | 兼容 CommonJS 和 ES 模块 |
十四、在 Vue 中使用 TypeScript
14.1 组件定义
<script setup lang="ts">
import { ref, computed } from 'vue'
interface User {
name: string
age: number
}
const user = ref<User>({
name: 'zhangsan',
age: 25
})
const doubleAge = computed(() => user.value.age * 2)
</script>
14.2 Props 类型
<script setup lang="ts">
interface Props {
title: string
count?: number
}
const props = defineProps<Props>()
</script>
14.3 Emit 类型
<script setup lang="ts">
interface Emits {
(e: 'update', value: string): void
(e: 'delete', id: number): void
}
const emit = defineEmits<Emits>()
</script>
十五、最佳实践
15.1 类型定义
// ✅ 好的做法
interface User {
name: string
age: number
}
// ❌ 避免
let user: any = { name: "zhangsan" }
15.2 函数类型
// ✅ 明确返回类型
function add(a: number, b: number): number {
return a + b
}
// ✅ 使用类型推断(简单函数)
const multiply = (a: number, b: number) => a * b
15.3 避免 any
// ❌ 避免使用 any
function process(data: any) {
// ...
}
// ✅ 使用具体类型或 unknown
function process(data: unknown) {
if (typeof data === 'string') {
// ...
}
}
十六、推荐资源
官方文档:
- TypeScript 官网:www.typescriptlang.org/
- TypeScript 中文网:www.tslang.cn/
学习资源:
- 《TypeScript 编程》
- 《深入理解 TypeScript》
- TypeScript 教程:www.runoob.com/typescript/…
十七、总结
TypeScript 核心要点:
静态类型 + 类型推断 + 接口 + 泛型 = 类型安全的 JavaScript
核心心法:
TypeScript 让 JavaScript 更安全、更可维护。 掌握类型系统是 TypeScript 开发的关键。
📝 文档信息
- 作者: 阿鑫
- 更新日期: 2026.1