TypeScript 联合类型入门:一个变量多种可能
前面写过类型标注入门,变量都有了固定类型。但现实里很多值不止一种可能:接口返回的可能是字符串也可能是 null,参数既接受数字也接受字符串。这时候就该联合类型(union type)出场了,写法是用竖线 | 把类型隔开。
基本用法:竖线隔开多个类型
let id: string | number;
id = 101; // 正确
id = "A101"; // 正确
// id = true; // 报错:boolean 不在联合里
function printId(value: string | number) {
console.log("当前 id 是:" + value);
}
printId(101); // 输出: 当前 id 是:101
printId("A101"); // 输出: 当前 id 是:A101
string | number 的意思是:这个位置要么是字符串,要么是数字,别的都不行。比起写成 any,联合类型把可能的范围说清楚了,超出照样报错。
类型收窄:先判断,再使用
联合类型的变量不能直接用某一类型的专属方法,因为类型系统不确定当前到底是哪个:
function len(value: string | number) {
// return value.toUpperCase(); // 直接调用会报错
if (typeof value === "string") {
return value.toUpperCase(); // 这里已知是 string
}
return value.toString(); // 走到这里只剩 number
}
console.log(len("abc")); // 输出: ABC
console.log(len(1024)); // 输出: "1024"
typeof 判断之后,if 分支里 TypeScript 就确认了它是 string,专属方法随便用。这个缩小范围的过程叫类型收窄(narrowing)。收窄方式不止 typeof,instanceof、in、甚至 !== undefined 的判断都算。
字面量类型:把取值限定成几个固定值
竖线两边也可以直接写字面量,用来表达"只允许这几个值":
type Direction = "up" | "down" | "left" | "right";
function move(dir: Direction) {
console.log("向 " + dir + " 移动");
}
move("up"); // 正确
// move("top"); // 报错:拼错单词当场拦下
let status: "loading" | "success" | "error" = "loading";
status = "success"; // 正确
这种写法在表示状态、开关、方向时特别好用,比随便传一个字符串安全得多——写错了编辑器直接划红线。
可空类型:类型 | null
最常见的联合其实是"正常值或空":
function findUser(name: string): string | null {
if (name === "雪梨") {
return "找到了";
}
return null; // 没找到时返回 null
}
const result = findUser("路人甲");
if (result !== null) {
console.log(result.toUpperCase()); // 收窄后才能放心调用
}
先把可能为 null 的情况挡掉,后面的代码才能放心用,这正是联合类型帮我们养成的习惯。
小结
- 联合类型用
|连接,表示"若干类型之一",比 any 精确得多 - 用之前先收窄:typeof / instanceof / in / 判空都行,收窄后才能调用专属方法
- 字面量联合
"a" | "b"适合限定状态和选项 类型 | null是最常见的联合,先判空再使用
把手里的 any 参数换成确切的联合类型,是给老代码补类型最划算的一步。
