TypeScript 1.6 引入了交叉类型作为联合类型 (union types) 逻辑上的补充. 联合类型 A | B 表示一个类型为 A 或 B 的实体, 而交叉类型 A & B 表示一个类型同时为 A 或 B 的实体.
例子
function extend<T, U>(first: T, second: U): T & U {
let result = <T & U> {};
for (let id in first) {
result[id] = first[id];
}
for (let id in second) {
if (!result.hasOwnProperty(id)) {
result[id] = second[id];
}
}
return result;
}
var x = extend({ a: "hello" }, { b: 42 });
var s = x.a;
var n = x.b;
type LinkedList<T> = T & { next: LinkedList<T> };
interface Person {
name: string;
}
var people: LinkedList<Person>;
var s = people.name;
var s = people.next.name;
var s = people.next.next.name;
var s = people.next.next.next.name;
interface A { a: string }
interface B { b: string }
interface C { c: string }
var abc: A & B & C;
abc.a = "hello";
abc.b = "hello";
abc.c = "hello";
interface Point {
x: number;
y: number;
}
function getPointFactory(x: number, y: number) {
class P {
x = x;
y = y;
}
return P;
}
var PointZero = getPointFactory(0, 0);
var PointOne = getPointFactory(1, 1);
var p1 = new PointZero();
var p2 = new PointZero();
var p3 = new PointOne();
本地的类型可以引用类型参数, 本地的类和接口本身即可能是泛型. 比如:
function f3() {
function f<X, Y>(x: X, y: Y) {
class C {
public x = x;
public y = y;
}
return C;
}
let C = f(10, "hello");
let v = new C();
let x = v.x; // number
let y = v.y; // string
}
let Point = class {
constructor(public x: number, public y: number) { }
public length() {
return Math.sqrt(this.x * this.x + this.y * this.y);
}
};
var p = new Point(3, 4); // p has anonymous class type
console.log(p.length());
abstract class Base {
abstract getThing(): string;
getOtherThing() { return 'hello'; }
}
let x = new Base(); // 错误, 'Base' 是抽象的
// 错误, 必须也为抽象类, 或者实现 'getThing' 方法
class Derived1 extends Base { }
class Derived2 extends Base {
getThing() { return 'hello'; }
foo() {
super.getThing();// 错误: 不能调用 'super' 的抽象方法
}
}
var x = new Derived2(); // 正确
var y: Base = new Derived2(); // 同样正确
y.getThing(); // 正确
y.getOtherThing(); // 正确
泛型别名
TypeScript 1.6 中, 类型别名支持泛型. 比如:
type Lazy<T> = T | (() => T);
var s: Lazy<string>;
s = "eager";
s = () => "lazy";
interface Tuple<A, B> {
a: A;
b: B;
}
type Pair<T> = Tuple<T, T>;
declare class Foo {
public x : number;
}
interface Foo {
y : string;
}
function bar(foo : Foo) {
foo.x = 1; // 没问题, 在类 Foo 中有声明
foo.y = "1"; // 没问题, 在接口 Foo 中有声明
}
用户定义的类型收窄函数
TypeScript 1.6 增加了一个新的在 if 语句中收窄变量类型的方式, 作为对 typeof 和 instanceof 的补充. 用户定义的类型收窄函数的返回值类型标注形式为 x is T, 这里 x 是函数声明中的形参, T 是任何类型. 当一个用户定义的类型收窄函数在 if 语句中被传入某个变量执行时, 该变量的类型会被收窄到 T.
例子
function isCat(a: any): a is Cat {
return a.name === 'kitty';
}
var x: Cat | Dog;
if(isCat(x)) {
x.meow(); // 那么, x 在这个代码块内是 Cat 类型
}