TypeScript 基本类型学习笔记

89 阅读6分钟

TypeScript 基本类型学习笔记

一、基本类型(Primitives)

  1. 核心类型:string(字符串,如"hello")、number(数字,如42,JavaScript 中整数和浮点数统一为此类型)、boolean(布尔值,true或false)。
  1. 注意事项:避免使用首字母大写的String、Number、Boolean,这些是特殊内置类型,日常开发应使用小写版本。

二、数组(Arrays)

  1. 类型表示
    • 语法 1:类型[](如number[]表示数字数组,string[]表示字符串数组);
    • 语法 2:Array<类型>(如Array,与number[]等价,后续泛型章节会详细说明)。
  1. 注意:[number]是元组(Tuples)类型,与数组不同,需区分。

三、any类型

  1. 特性:any类型可绕过类型检查,允许访问任意属性、调用函数、赋值给任意类型,例如:
let obj: any = { x: 0 };
obj.foo(); // 无编译错误
obj = "hello"; // 允许赋值字符串
  1. noImplicitAny 选项:当变量类型未指定且无法推断时,默认会隐式为any。启用noImplicitAny可将隐式any标记为错误,强制显式声明类型,避免失去类型检查意义。

四、变量类型注解

  1. 语法:声明变量时可添加:指定类型,如let myName: string = "Alice"。
  1. 类型推断:TypeScript 通常能自动推断变量类型(如let myName = "Alice"会被推断为string),无需显式注解,建议优先依赖推断。

五、函数(Functions)

  1. 参数类型注解:在参数名后添加:指定类型,如function greet(name: string) { ... },传入参数类型不匹配时会报错。
  1. 返回类型注解:在参数列表后添加:指定返回类型,如function getNum(): number { return 10; }。异步函数返回类型需用Promise<类型>(如async function fn(): Promise { ... })。
  1. 匿名函数:上下文会自动推断参数类型(上下文类型推断),例如数组的forEach回调函数参数可省略类型注解:
const names = ["Alice", "Bob"];
names.forEach((s) => { console.log(s.toUpperCase()); }); // s 自动推断为 string

六、对象类型(Object Types)

  1. 基本定义:通过列出属性及类型描述对象结构,如{ x: number; y: number }表示包含x和y两个数字属性的对象。
  1. 可选属性:属性名后加?表示可选(如{ first: string; last?: string }),访问时需处理undefined(如通过if判断或可选链?.):
function printName(obj: { first: string; last?: string }) {
  console.log(obj.last?.toUpperCase()); // 安全访问可选属性,等同于 obj.last !== undefined 比较后执行
}

七、联合类型(Union Types)

  1. 定义:由两个或多个类型组成的类型,表示值可以是其中任意一种,语法为类型1 | 类型2(如number | string表示数字或字符串),联合成员的分隔符也可以放在第一个元素之前。
  1. 类型收窄(Narrowing) :通过代码逻辑让 TypeScript 推断更具体的类型,常见方式:
function printId(id: number | string) {
  if (typeof id === "string") {
    console.log(id.toUpperCase()); // 此处id被收窄为string
  } else {
    console.log(id); // 此处id被收窄为number
  }
}
    • 使用typeof判断(如typeof id === "string");
    • 使用Array.isArray判断数组(如Array.isArray(x));

八、类型别名(Type Aliases)

  1. 作用:为任意类型命名,便于复用,语法为type 别名 = 类型
type Point = { x: number; y: number }; // 为对象类型命名
type ID = number | string; // 为联合类型命名
  1. 特性:仅为类型起别名,不创建新类型,不同别名指向同一类型时可互相赋值。

九、接口(Interfaces)

  1. 作用:用于描述对象类型的结构,语法为interface 接口名 { 属性: 类型 }
interface Point { x: number; y: number }
function printCoord(pt: Point) {  // 与类型别名用法类似
   console.log("The coordinate's x value is " + pt.x);
   console.log("The coordinate's y value is " + pt.y);
}
printCoord({ x: 100, y: 100 });
  1. 与类型别名的区别
特性接口(interface)类型别名(type)
扩展方式使用extends(如interface Bear extends Animal { ... })使用交叉类型&(如type Bear = Animal & { ... })
重复声明可重复声明并合并属性(如interface Window { a: number }后再声明interface Window { b: string },最终包含a和b)不可重复声明,会报错
适用场景主要用于描述对象结构可描述任意类型(对象、联合类型等)
  1. 建议优先使用interface,需使用类型别名特性(如描述联合类型)时再用type。

十、类型断言(Type Assertions)

  1. 作用:当开发者比 TypeScript 更清楚值的类型时,手动指定类型(不影响运行时,仅编译期有效)。
  1. 语法
    • 方式 1:值 as 类型(如const canvas = document.getElementById("canvas") as HTMLCanvasElement);
    • 方式 2:<类型>值(如<HTMLCanvasElement>document.getElementById("canvas"),.tsx文件中不支持)。
  1. 限制:仅允许断言为更具体或更宽泛的类型,不可直接断言为无关类型(如"hello" as number会报错)。若需强制转换,可先断言为any再转目标类型(如"hello" as any as number)。

十一、字面量类型(Literal Types)

  1. 定义:具体的值作为类型,如字符串字面量"hello"、数字字面量42、布尔字面量true。
  1. 常用场景:结合联合类型限制取值范围,类似枚举类型,例如:
function printText(alignment: "left" | "right" | "center") { ... }
printText("left"); // 合法
printText("centre"); // 报错(不在允许范围内)
  1. 字面量推断与 as const
    • 变量初始化时,TypeScript 默认推断为宽泛类型(如const obj = { method: "GET" }中method被推断为string);
    • 使用as const可强制推断为字面量类型(如const obj = { method: "GET" } as const中method被推断为"GET")。

十二、null与undefined

  1. strictNullChecks 配置影响
    • 关闭时:null和undefined可赋值给任意类型,无需检查;
    • 开启时:需显式处理null/undefined,可通过类型收窄(如if (x !== null))或可选链(?.)避免错误。
  1. 非空断言运算符( ! :在值后加!表示断言其不为null/undefined(如x!.toFixed()),仅在确定值非空时使用。

十三、枚举(Enums)

  • 是 TypeScript 新增特性,用于定义命名常量集合(非类型层面扩展,影响运行时)。
  • 建议:除非确有必要,否则谨慎使用,优先考虑联合字面量类型

十四、不太常见的基本类型

  1. bigint:用于超大整数,声明方式为const num: bigint = 100n或BigInt(100)。
  1. symbol:用于创建全局唯一标识,通过Symbol()生成,不同Symbol即使描述相同也不相等(如Symbol("name") !== Symbol("name"))。

总结

日常开发中,需熟练掌握基本类型、数组、函数、对象、联合类型等核心概念,理解类型推断与注解的平衡,合理使用类型别名与接口,以及通过类型收窄处理复杂类型场景。严格模式(如strictNullChecks)虽增加初期工作量,但能显著减少运行时错误,建议新项目启用。

参考 TypeScript:文档——日常类型 --- TypeScript: Documentation - Everyday Types