LK 博客
基于 JavaScript 的 TypeScript 学习笔记
前后端
约 1 分钟阅读 1 赞 0 条评论 鸿蒙黑体

基于 JavaScript 的 TypeScript 学习笔记

栗树林在山岗
栗树林在山岗 @栗树林在山岗
累计点赞 1 登录后每个账号只能点一次
内容长度 0 正文词元数
正文
目录会跟随阅读位置移动。
阅读进度

基于 JavaScript 的 TypeScript 学习笔记

一、TypeScript 是什么?

  • TS = JS + 类型系统:所有 JS 代码都是 TS 代码,TS 在编译时进行类型检查
  • 最终编译成纯 JS,在浏览器/Node.js 中运行

二、基础类型(对比 JS)

JS 写法 TS 写法
let a = 10 let a: number = 10
let b = 'hi' let b: string = 'hi'
let c = true let c: boolean = true
let d = null let d: null = null
let e = undefined let e: undefined = undefined
let f = [1,2,3] let f: number[] = [1,2,3]Array<number>
let g = {name:'Tom'} let g: {name: string} = {name:'Tom'}

TS 新增类型

  • any:关闭类型检查(尽量少用)
  • unknown:安全的任意值(使用前需类型断言)
  • void:无返回值
  • never:永远不会发生(如抛出错误)
  • tuple:固定长度数组,如 [string, number]

三、类型注解与类型推断

// 自动推断
let age = 25;  // 等价于 let age: number = 25

// 需要显式注解的情况
let user: { name: string; age?: number };
let callback: (x: number) => void;

四、函数类型注解

// 参数和返回值都要加类型
function add(a: number, b: number): number {
  return a + b;
}

// 箭头函数
const add = (a: number, b: number): number => a + b;

// 可选参数
function greet(name: string, age?: number): string {
  return age ? `${name} is ${age}` : name;
}

// 默认参数
function multiply(a: number, b: number = 1): number {
  return a * b;
}

五、接口(Interface)

interface User {
  name: string;
  age: number;
  email?: string;      // 可选属性
  readonly id: number; // 只读属性
}

const tom: User = {
  name: 'Tom',
  age: 18,
  id: 1
};

接口 vs 类型别名(type):

  • 接口:主要用于对象/函数形状,可重复声明合并
  • 类型别名:可用于任何类型,不可重复声明

六、联合类型与类型守卫

1.联合类型

联合类型 是 TypeScript 中一种强大的类型系统特性,允许一个变量同时拥有多种可能的类型,用竖线 | 分隔。

// 变量可以是 string 或 number
let id: string | number;
id = 'abc123';   // 合法
id = 456;        // 合法
id = true;       // 错误,boolean 不在联合类型中

// 函数参数可以是多种类型
function format(value: string | number): string {
  return value.toString();
}

联合类型的问题与解决

问题:只能访问所有类型的共同成员

let id: string | number = 'abc';

// 错误:number 没有 toUpperCase 方法
console.log(id.toUpperCase());

// 错误:string 没有 toFixed 方法
console.log(id.toFixed(2));

// 可以访问共同成员(所有类型都有 toString)
console.log(id.toString());  // string 和 number 都有 toString

解决方案:类型守卫

2.类型守卫

类型守卫是 TypeScript 中用来在运行时检查类型的一种机制,它让 TS 能够在某个作用域内智能地缩小类型的范围。

为什么需要类型守卫?

当你使用联合类型时,TS 不确定具体是哪种类型,很多操作无法直接进行。

function printId(id: string | number) {
  console.log(id.toUpperCase()); // 错误:number 没有 toUpperCase 方法
  console.log(id.toFixed(2));    // 错误:string 没有 toFixed 方法
}

守卫方式:

(1)typeof 守卫(适用于基本类型)

function printId(id: string | number) {
  if (typeof id === 'string') {
    console.log(id.toUpperCase()); //  TS 知道这里是 string
  } else {
    console.log(id.toFixed(2));    // TS 知道这里是 number
  }
}

(2)instanceof 守卫(适用于类/对象)

class Dog { bark() { console.log('汪汪'); } }
class Cat { meow() { console.log('喵喵'); } }

function makeSound(animal: Dog | Cat) {
  if (animal instanceof Dog) {
    animal.bark(); // TS 知道这里是 Dog
  } else {
    animal.meow(); // TS 知道这里是 Cat
  }
}

(3)in 守卫(检查属性是否存在)

interface Fish { swim(): void; }
interface Bird { fly(): void; }

function move(animal: Fish | Bird) {
  if ('swim' in animal) {
    animal.swim(); // TS 知道这里有 swim 方法
  } else {
    animal.fly();  // TS 知道这里有 fly 方法
  }
}

(4) 自定义类型守卫(is 关键字)

interface Cat {
  name: string;
  meow(): void;
}

function isCat(animal: any): animal is Cat {
  return animal && typeof animal.meow === 'function';
}

function handle(animal: Cat | Dog) {
  if (isCat(animal)) {
    animal.meow(); // TS 知道这里是 Cat
  }
}

七、数组和元组

// 数组
let list: number[] = [1, 2, 3];
let list2: Array<string> = ['a', 'b'];

// 元组(固定长度,每个位置类型固定)
let point: [number, number] = [10, 20];
let httpResponse: [number, string] = [200, 'OK'];

八、类型断言

当你比TS更了解某个值的类型时使用

let someValue: unknown = 'hello world';

// 方式1:as 语法(推荐)
let strLength: number = (someValue as string).length;

// 方式2:尖括号语法(JSX 中不可用)
let strLength2: number = (<string>someValue).length;

九、常用类型工具

interface Person {
  name: string;
  age: number;
  email: string;
}

type WithoutEmail = Omit<Person, 'email'>;      // 排除 email
type PartialPerson = Partial<Person>;           // 全部变为可选
type ReadonlyPerson = Readonly<Person>;         // 全部变为只读
type NameAndAge = Pick<Person, 'name' | 'age'>; // 只选 name 和 age

十、tsconfig.json核心配置

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "strict": true, // 开启全部严格检查
    "esModuleInterop": true,
    "skipLibCheck": true,
    "outDir": "./dist",
    "rootDir": "./src"
  }
}

作者名片

栗树林在山岗
栗树林在山岗
@栗树林在山岗

这个作者暂时还没有填写个人简介。

评论区
文章作者和管理员都可以管理这里的评论。
0 条评论
登录后即可参与评论。 去登录
还没有评论,欢迎留下第一条交流内容。