JavaScript有7种类型:Boolean、Number、String、Undefined、Null、Object,以及ES6新增的Symbol
这7种TypeScript全都支持:
// JavaScript支持的7种类型
let isDone: boolean = false; // 布尔值
let decimal: number = 6; // 数值
let color: string = 'blue'; // 字符串
let u: undefined = undefined; // Undefined
let n: null = null; // Null
let obj: object = {}; // Object
let sym: symbol = Symbol(); // Symbol
上面示例中的变量都是通过let
声明的,其实有3种变量声明方式:
var
:函数作用域let
:块级作用域const
:块级作用域,常量(不允许修改)例如:
var a: string = 'a';
let b: string = 'b';
const c: string = 'c';
与JavaScript变量声明方式完全一致,不再赘述,具体见Variable Declarations
P.S.实际上,let
和const
最终都会被编译成var
,块级作用域等特性通过变量重命名来模拟
TypeScript共有13种基本类型,除了JavaScript所有的7种之外,还有:
any
类型绕过类型检查示例如下:
// TypeScript新增的6种类型
let list: number[] = [1, 2, 3]; // 数组
let list: Array<number> = [1, 2, 3]; // 数组
let x: [string, number] = ["hello", 10]; // 元组
enum Color {Red = 'r', Green = 'g', Blue = 'b'} // 枚举
let notSure: any = 4; // 任意类型
let list: any[] = [1, true, "free"]; // 任意类型数组(未知类型)
function warnUser(): void {/*..*/} // 空类型
function neverReturn(): never {throw 'error';} // 绝不存在的类型
需要注意几点:
elemType []
和Array<elemType>
)x[10]
的类型是string | number
0
开始。如果指定了数值,后一项的值在此基础上递增,否则要求之后的项都要指定值(默认的数值递增机制应付不了了)undefined
或null
let str: string = null
也是合法的)declare const name: never;
避免隐式访问window.name
)P.S.特殊的,建议开启--strictNullChecks
选项,此时Undefined
和Null
只允许赋值给Void以及各自对应的类型
P.S.关于Never作为类型保护的应用,见Improve type safety of name global variable
可以通过类型断言告知TypeScript编译器某个值的确切类型:
Type assertions are a way to tell the compiler “trust me, I know what I’m doing.”
类似于其它语言里的强制类型转换(type casting),区别在于类型断言只是编译时的,不像类型转换一样具有运行时影响:
A type assertion is like a type cast in other languages, but performs no special checking or restructuring of data. It has no runtime impact, and is used purely by the compiler.
有两种语法格式,分别是<type>
和as type
,例如
let someValue: any = "this is a string";
// <type>
let strLength: number = (<string>someValue).length;
// as type
let strLength: number = (someValue as string).length;
两种方式等价,但在JSX中只能用as type
(尖括号语法与JSX语法冲突)
实际上,TypeScript枚举类型建立了key-value的双向索引,例如:
enum Color {Red = 1, Green, Blue}
// 对应的JavaScript为
var Color;
(function (Color) {
Color[Color["Red"] = 1] = "Red";
Color[Color["Green"] = 2] = "Green";
Color[Color["Blue"] = 3] = "Blue";
})(Color || (Color = {}));
// 得到
// {1: "Red", 2: "Green", 3: "Blue", Red: 1, Green: 2, Blue: 3}
因此,一个有意思的技巧是根据枚举值访问key:
let colorName: string = Color[2];
// 此时,colorName为'Green'
Any类型用来绕过编译时类型检查,因此可以用来修改一些不能改的东西,例如:
window.customFunction = myCustomFunction;
编译报错:
Property ‘customFunction’ does not exist on type ‘Window’.
可以通过any
类型绕过:
const globalAny: any = window;
globalAny.customFunction = myCustomFunction;
或者等价的类型断言:
(<any> window).customFunction = myCustomFunction;
// 或
(window as any).customFunction = myCustomFunction;