Skip to content

联合类型

TypeScript 的类型系统允许你使用多种运算符,从现有类型中构建新类型。现在我们知道如何编写几种类型,是时候开始以有趣的方式组合它们了。

  • 定义联合类型 第一种组合类型的方法是联合类型。联合类型是由两个或多个其他类型组成的类型,表示可能是这些类型中的任何一种的值。我们将这些类型中的每一种称为联合类型的成员。

让我们编写一个可以对字符串或数字进行操作的函数:

typescript
function printId(id: number | string) { 
  console.log("Your ID is: " + id); 
}
// 正确 
printId(101); 
// 正确 
printId("202"); 
// 错误 
printId({ myID: 22342 });

使用联合类型

  • 提供匹配联合类型的值很容易- 只需提供匹配任何联合成员的类型。如果你有一个联合类型的值,你如何使用它?
  • 如果联合的每个成员都有效,TypeScript 将只允许你使用联合做一些事情。例如,如果你有联合类型 string | number ,则不能只使用一种类型的操作,比如 string :
typescript
function printId(id: number | string) { 
  console.log(id.toUpperCase()); 
}

解决方案是用代码缩小联合,就像在没有类型注释的 JavaScript 中一样。 当 TypeScript 可以根据代码结构为值推断出更具体的类型时,就会发生缩小。 例如,TypeScript 知道只有一个 string 值才会有一个 typeof 值 "string" :

typescript
function printId(id: number | string) { 
  if (typeof id === "string") { 
    // 在此分支中,id的类型为“string” 
    console.log(id.toUpperCase()); 
  } else { 
    // 此处,id的类型为“number” 
    console.log(id); 
  } 
}

另一个例子是使用如下函数 Array.isArray :

typescript
function welcomePeople(x: string[] | string) { 
  if (Array.isArray(x)) { 
    // 此处: 'x' 的类型是 'string[]' 
    console.log("Hello, " + x.join(" and ")); 
  } else { 
    // 此处: 'x' 的类型是 'string' 
    console.log("Welcome lone traveler " + x); 
  } 
}

请注意,在 else 分支中,我们不需要做任何特别的事情——如果 x 不是 string[] ,那么它一定是 string 。

有时你会有一个 union ,所有成员都有一些共同点。例如,数组和字符串都有一个 slice 方法。如果联合中的每个成员都有一个共同的属性,则可以使用该属性而不会缩小范围:

typescript
// 返回类型推断为 number[] | string 
function getFirstThree(x: number[] | string) { 
  return x.slice(0, 3); 
}