# 类型推断二三事

# 任意值 (新)

任意值(Any)用来表示允许赋值为任意类型。

# 什么是任意值类型

如果是一个普通类型,在赋值过程中改变类型是不被允许的:

let myFavoriteNumber: string = "seven";
myFavoriteNumber = 7;

// Type 'number' is not assignable to type 'string'.

但如果是 any 类型,则允许被赋值为任意类型。

let myFavoriteNumber: any = "seven";
myFavoriteNumber = 7;

# 任意值的属性和方法

在任意值上访问任何属性都是允许的:

let anyThing: any = "hello";
console.log(anyThing.myName);
console.log(anyThing.myName.firstName);

也允许调用任何方法:

let anyThing: any = "Tom";
anyThing.setName("Jerry");

方法的返回值也是如此:

let anyThing: any = "Tom";
anyThing.setName("Jerry");
anyThing.setName("Jerry").sayHello();

可以认为,声明一个变量为任意值之后,对它的任何操作,返回的内容的类型都是任意值。

变量如果在声明的时候,未指定其类型,那么它会被识别为任意值类型。

let something;
something = "seven";
something = 7;

等价于

let something: any;
something = "seven";
something = 7;

# 类型推断

如果没有明确的指定类型,那么 TypeScript 会依照类型推论(Type Inference)的规则推断出一个类型。

# 什么是类型推论

TypeScript 会在没有明确的指定类型的时候推测出一个类型,这就是类型推论。

以下代码虽然没有指定类型,但是会在编译的时候报错:

let myFavoriteNumber = "seven";
myFavoriteNumber = 7;

// index.ts(2,1): error TS2322: Type 'number' is not assignable to type 'string'.

事实上,它等价于:

let myFavoriteNumber: string = "seven";
myFavoriteNumber = 7;

# 联合类型

如果变量只能拥有一种类型,那么有些情况就会变得很不好处理。

联合类型(Union Types)表示取值可以为多种类型中的一种。

# 简单的例子

let myFavoriteNumber: string | number;
myFavoriteNumber = "seven"; // √
myFavoriteNumber = 7; // √
myFavoriteNumber = true; // ×
// Type 'boolean' is not assignable to type 'string | number'.
let arr: (string | number)[] = ["1", 2];

# 访问联合类型的属性或方法

当 TypeScript 不确定一个联合类型的变量到底是哪个类型的时候,我们只能访问此联合类型的所有类型里共有的属性或方法。

function getLength(something: string | number): number {
  return something.length;
}

由于数字类型不具备lenght属性,所以为报错。

// Property 'length' does not exist on type 'string | number'.
// Property 'length' does not exist on type 'number'.

联合类型的变量在被赋值的时候,会根据类型推论的规则推断出一个类型

let myFavoriteNumber: string | number;
myFavoriteNumber = "seven";
console.log(myFavoriteNumber.length); // 5
myFavoriteNumber = 7;
console.log(myFavoriteNumber.length); // 编译时报错