前端-TypeScript基础知识

25 阅读6分钟

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

特性InterfaceType
扩展使用 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 核心要点:

静态类型 + 类型推断 + 接口 + 泛型 = 类型安全的 JavaScript

核心心法:

TypeScript 让 JavaScript 更安全、更可维护。 掌握类型系统是 TypeScript 开发的关键。


📝 文档信息

  • 作者: 阿鑫
  • 更新日期: 2026.1