TypeScript 高级类型

⒈交叉类型(Intersection Types)

  交叉类型是将多个类型合并为一个类型。 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。 例如, Person & Serializable & Loggable同时是 Person 和 Serializable 和 Loggable。 就是说这个类型的对象同时拥有了这三种类型的成员。

  每当我们正确的使用交叉类型的时候,TypeScript可以帮我们合理地将两个不同类型叠加为新的类型,并包含了所需的所有类型。

  我们大多是在混入(mixins)或其它不适合典型面向对象模型的地方看到交叉类型的使用。 (在JavaScript里发生这种情况的场合很多!)

type newType = number & string;
let a : newType;


interface A{
  a:number,
  b:string,
}
interface B{
  c:string,
  d:string,
}
type newType2 = A & B;
let b : newType2;

  这里的Type关键字是用来声明类型变量的。在运行时,与类型相关的代码都会被移除掉,并不会影响到JavaScript的执行。

  *当交叉类型中有属性冲突时,则无论如何赋值都不可能通过类型检查。如下面的代码所示:

interface A{
  a:number,
  b:string,
}
interface B{
  c:string,
  d:string,
}
type newType = A & B;
let a : newType = {a:1,b:'',c:'',d:''};
a.a = 1;
a.b = '';
a.c = '';
a.d = 5;  //Error,无法通过类型检查

⒉联合类型(Union Types)

  联合类型与交叉类型类似,但使用上却完全不同。

  例如我们需要一个变量可能是number,也有可能是string,这是一个很常见的场景,联合类型便是用于解决这样的问题。

  比如下面这段经典的函数:

function padLeft(value: string, padding: any) {
    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}'.`);
}

padLeft("Hello world", 4); // returns "    Hello world"

  padLeft函数存在一个问题, padding参数的类型指定为 any。 也就是说,我们可以传入一个既不是 number也不是 string类型的参数,但是TypeScript却不报错。

let indentedString = padLeft("Hello world", true); // 编译阶段通过,运行时报错

  在传统的面向对象语言里,我们可以使用重载或将这两种类型抽象成有层级的类型(父类与子类)。 这么做显然是非常清晰的,但同时也存在了过度设计。

  因为在JavaScript中并没有重载可以使用(可以使用特殊的方式创建出类似重载的函数),因此在JavaScript的函数中手动去判断参数的类型这种操作更为常见,这在一定程度上避免了过度设计。

   padLeft原始版本的好处之一是允许我们传入原始类型。 这样做的话使用起来既简单又方便。 如果我们就是想使用已经存在的函数的话,这种新的方式就不适用了。

  如果我们希望更准确的描述padding的类型,就可以使用联合类型将padding的类型限定为既可以是number又可以是string。

  代替 any, 我们可以使用 联合类型作为 padding的参数:

function padLeft(value: string, padding: string | number) {
  // ...
}

let indentedString = padLeft("Hello world", true); // 编译器报错,类型true的参数不能赋值给类型string|number的参数

  联合类型表示一个变量可以是几种类型之一。 我们用竖线( |)分隔每个类型,所以 number | string | boolean表示一个值可以是 numberstring或 boolean

  注意,如果一个值是联合类型,我们只能访问它们共有的属性。

  我们来看一下下面的例子:

  

猜你喜欢

转载自www.cnblogs.com/fanqisoft/p/11939900.html