Typescript的数据类型
typescript为了使编写的代码更规范,更有利于维护,增加了类型校验,在typescript中主要提供了以下类型
数据类型
- 布尔类型(boolean)
- 数字类型(number)
- 字符串类型(string)
- 数组类型(array)
- 元组类型(tuple)
- 枚举类型(enum)
- 任意类型(any)
- null 和 undefined
- void类型
- never类型
var flag = true;flag = 456; // ES5可以这样写,但在typescript中,此处会在编写时报错// 指定变量类型var flag:boolean = true; // 布尔类型var str:string = 'hello'; // 字符串类型var num1:number = 123; // 数字类型// any类型可以赋任意类型的值var num:any = 123;num = true;num = 'abc';// 第1种定义数组的方式var arr:number[] = [12, 5, 8];// 第2种定义数组的方式var arr:Array<number> = [12, 5, 8];// 元组类型,属于数组的一种,可以为数组中每一个位置元素指定一个类型let arr:[number, string, string] = [12, "abc","123"];
// 枚举类型// 枚举类型中间没有等号enum Flag {success = 1, error = 2};// 如果定义一个数字枚举,第一个成员初始化为1,其余成员会自动从1开始增长enum Direction {Up = 1, // 如果不指定Up初始化值,则 Up的值为0,Down为1Down, // Up = 1时,Down会自动变成2Left,Right}// 使用let s:Flag = Flag.success;console.log(s); // 输出1// 如果枚举的标识符没有赋值,打印出来的为前一个的值加1。如果第一项没有值,则第一项值默认为0enum Color {blue, red, yellow = 3, green, 'white'};console.log(Color.blue); // 0console.log(Color.red); // 1console.log(Color.yellow); // 3console.log(Color.green); // 4console.log(Color.white); // 5
// null和undefined 是其他数据类型(never类型)的子类型// 定义为具体类型的变量,不能为undefined,即不能不初始化一个值。但是定义为undefined类型的变量可以不进行初始化// 所以可以将变量定义为 具体类型变量 或 undefined类型var num: number | undefined | null ; // 此时num即可以为空,也可以赋数字的值// 类似的,一个变量可以定义为多种类型var a:number | string = 123;a = 'abc';
// void类型: 表示没有任何类型,一般用于定义方法的时候没有返回值function run():void{console.log('run');}// 声明一个void类型的变量没有什么作用,因为它只能被赋予undefined和nulllet unusable: void = undefined;
// undefined和null类型本身的类型用处不是很大// never类型: 是其他类型(包括null和undefined)的子类型,代表从不会出现的值,就是说可以把null和undefined赋值给number、string等类型的变量。然而一旦指定了 --strictNullChecks标记,null和undefined就只能赋值给void和它们各自,想给string传入一个null或undefined时需要指定联合类型: string | null | undefined// 这意味着声明never的变量只能被never类型所赋值// undefined只能赋值undefined,null只能赋值nullvar a:undefined;a = undefined;var b:null;b = null;// never表示从不会出现的值,例如throw一个错误// never类型是任何类型的子类型,可以赋值给任何类型// 没有类型是never类型的子类型或赋值给never类型(除了never本身)// 一般情况下用不到// 返回never的函数必须存在无法到达的终点:例如抛出异常、死循环var c:never;c = (() =>{throw new Error('错误');})();function infiniteLoop():never {while(true){}}
类型断言
当自己知道某个变量的类型时,可以通过类型断言这种方式告诉编译器。类型断言好比其他语言中的类型转换,但是不进行特殊的数据检查和结构,它没有运行时影响,只在编译阶段起作用。
- 使用尖括号进行类型断言
let someValue: any = 'I konw this is a string';let strLength: number = (<string>someValue).length; // 使用尖括号断言someValue为string类型
- 使用as进行断言
let someValue: any = 'I konw this is a string';let strLength: number = (someValue as string).length; // 使用as语法断言someValue为string类型
- 使用感叹号后缀去除类型中的null和undefined ```typescript // indetifier! 从identifier类型中去除null和undefined
function fixed(name: string | null): string { //本例使用了嵌套函数,因为编译器无法去除嵌套函数的null(除非是立即调用的函数表达式)。 因为它无法跟踪所有对嵌套函数的调用,尤其是你将内层函数做为外层函数的返回值。 如果无法知道函数在哪里被调用,就无法知道调用时 name的类型。 function postfix(epithet: string) { return name!.charAt(0) + ‘. the ‘ + epithet; // ok } name = name || “Bob”; return postfix(“great”); }
-使用js的(+)操作符把字符串转换成数字```typescriptlet a: string = '123';let b: number = +a; // 使用加号将字符串转换为数字
交叉类型
交叉类型是将多个类型合并为一个类型。 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。 例如, Person & Serializable & Loggable同时是 Person 和 Serializable 和 Loggable。 就是说这个类型的对象同时拥有了这三种类型的成员
联合类型
联合类型与交叉类型很有关联,但是使用上却完全不同。 偶尔你会遇到这种情况,一个代码库希望传入 number或 string类型的参数。
// 联合类型表示一个值可以是几种类型之一。 我们用竖线( |)分隔每个类型,所以 number | string | boolean表示一个值可以是 number, string,或 boolean。function padLeft(value: string, padding: string | number) {// ...}
类型保护
- typeof类型保护
这些
typeof类型保护只有两种形式能被识别:typeof v === "typename"和typeof v !== "typename","typename"必须是"number","string","boolean"或"symbol"。 但是TypeScript并不会阻止你与其它字符串比较,语言不会把那些表达式识别为类型保护。
if (typeof padding === "number") {// ....}
- instanceof类型保护
instanceof类型保护是通过构造函数来细化类型的一种方式
if (padder instanceof SpaceRepeatingPadder) {// ....}
类型别名
给类型起一个新的名字
type Name = string;type NameResolver = () => string;type NameOrResolver = Name | NameResolver; // 联合类型type Container<T> = { value: T }; // 泛型type Easing = "ease-in" | "ease-out" | "ease-in-out"; // 字面量类型// 类型别名中可以使用自己type Tree<T> = {value: T;left: Tree<T>;right: Tree<T>;}// 错误用法:type Yikes = Array<Yikes>;
类别名与交叉类型一起使用:
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;
