一、基本数据类型
Javascript 的类型分为两种:原始数据类型和对象类型,TypeScript 支持与JavaScript几乎相同的数据类型,此外还提供了枚举、元组等实用的类型。基本数据类型包括:数值、字符串、布尔值、null、undefine、void 以及 ES6 新增的 symbol。
1、数值类型
let decNum : number = 12let drNum : number = NaNlet infinityNum : number = Infinity// ES6 中的二进制表示法(0b 或者 0B 开头)let binaryLiteral: number = 0b1010;// ES6 中的八进制表示法(0o 或者 0O 开头)let octalLiteral: number = 0o744;
2、字符串类型
// 普通字符串let myName : string = 'song jun bo'// 模板字符串let sentence : string = `This is my name${myName}`
3、布尔值
let isDone: boolean = false;
4、null 和 undefined 类型
在 Typescript 中 使用 null 和 undefined 来定义这两个数据类型。
let n : null = nulllet un : undefined = undefined
5、void 空类型
空类型顾名思义表示没有任何类型,常见于函数中,当函数不需要返回值时可以指定返回值为空类型。
function warnUser(): void { // 一些逻辑代码,不需要返回值}
6、symbol类型
定义一个symbol 类型变量
let sym : symbol
调用Symbol 构造函数,创建变量
let sy1 : symbol = Symbol()let sy2 : symbol = Symbol()console.log(sy1 === sy1) // false
构造函数可传入如参数,symbol 是不可变且唯一的,即使Symbol 构造函数传入的key值一样
let sy3 : symbol = Symbol('same')let sy4 : symbol = Symbol('same')console.log(sy3 === sy4) // false
symbol 可以和字符串一样作为对象的 key,由于symbol 唯一,因此,作为对象属性的key可避免对象属性覆盖问题
let symKey = Symbol();let obj = { [symKey]: "value"};console.log(obj[sym]); // "value"
二、Typescript中的任意类型
有时候,在编程阶段,我们并不知道或者并不想为一个变量指定一个类型,因为有可能这个这个变量来自第三方库,或者来自用户输入。这个时候可以使用any 任意类型,任意类型变量可避开typescript 类型检查器的检查。
下面的例子定义了任意类型的变量myFavoriteNumber,这个变量既可以被赋值为string 类型的值也可以被赋值为 number类型的值。let myFavoriteNumber: any = 'seven';myFavoriteNumber = 7;
值得注意的是,任意值的属性和方法,在任意值上访问任何属性和方法都是可以的。比如定义任意类型变量 anything,并调用setName 方法,虽然anyThing 上没有setName 函数,但ts类型检查的时候不会报错,运行阶段才会报错,这个侧面说明静态类型语言的好处,将报错扼杀在摇篮之内。
let anyThing : any = 'string'anyThing.setName('name')
另外一点需要特别注意,声明一个any 类型的变量之后,对它的任何操作,返回的内容的类型都是任意值,如果声明变量的时候未指定其类型,会被默认推断为任意类型,如:
let someThing;someThing = 'string'someThing = 100
等同于
let someThing:any someThing = 'string'someThing = 1000
三、Typescript中的元组
元组类似数组,只不过元组可以指定元组中各个元素的类型,并且各元素的类型不必相同,如:
let tuple : [String,Number] = ['tupleName',123]
和数组一样,元组可用角标取值,如:
console.log(tuple[0]) // tupleNameconsole.log(tuple[1]) // 123
同样的,元组可以通过角标为元组变量赋值
tuple[0] = 'tupleName2'tuple[1] = 456
注意,当赋值给越界的元组时,它的类型会被限制为元组中每个类型的联合类型
tuple[2] = 'www.baidu.com' // 可行,因为该元组的联合类型为 string | numbertuple[2] = false //报错,因为该元组的联合类型为 string | number
注意:当直接为元组变量初始化或者赋值时,需提供元组类型中所有指定的项
let tuple2 : [String,Number]tuple2 = ['tuple2'] //会报错tuple2[0] = 'tuple2' // 会报错let tuple2 : [String,Number] = ['tuple2',124]
四、Typescript中的类型推断
如果定义的变量没有为他明确指明一个类型,Typescript 会依照类型推论的规则推断出一个类型。
let myType = 'string' //这里实际上等价于 let myType : string = 'string' myType = 44 // 报错,因为此时,myType 变量被推断为 string 类型,不能再被赋值为number类型
注意:如果声明一个变量的时候没有明确指定类型且没有赋值,那么不管之后有没有赋值都会被推断为任意类型而完全不会被类型检查。
let myType // 此时相当于 let myType:anymyType = 'myType'myType = 100
五、Typescript中的联合类型
联合的类型的作用是可以为变量定义多个类型,多种类型之间用 “ | ” 分格
let myTypeUnion : string | number myTypeUnion = 'string'myTypeUnion = 100myTypeUnion = false // 报错,因为 联合类型中并没有 boolean 类型
注意:Typescript 不确定联合类型的变量究竟是哪个类型的时候 ,只能访问此联合类型所有类型共有的属性和方法
function getMyTypeUnion(myParam:string|number){ // return myName.length // 报错,因为length不是 string 类型和number 类型共有的属性 return myParam.toString() //正常,因为 toString() 是共有的函数,}
另外一个例子,结合接口概念:
interface Bird { fly(); layEggs();}interface Fish { swim(); layEggs();}function getSmallPet(): Fish | Bird { let fish = { swim(){ }, layEggs(){ } } return fish}let pet = getSmallPet();pet.layEggs(); // 正常,因为 layEggs 方法是接口 Fish 和 Bird 共有的pet.swim(); // 报错,因为swim方法不是 接口 Fish 和 Bird 共有的
六、Typescript中的类型断言
类型断言允许自己断定某个变量的类型。
语法: <类型>值 或者 值 as 类型第四点联合类型说到,联合类型只能访问共有的属性和方法,引用非共有的属性或者方法类型检查机制是不允许的,当然你可以像在 Javascript 中那样通过 if else 判断来区分不同类型然后调各自类型的属性和方法,如:function getMyTypeUnionAsert(myParam:string|number){ // return myName.length // 报错因为,length不是 string 类型和number 类型共有的属性 // return myParam.toString() //不报错,因为 toString() 是共有的函数, if( typeof(myParam)=='string' ){ return myParam.length } if( typeof(myParam)=='number' ){ return myParam.toFixed(2) }}let resultAsert = getMyTypeUnionAsert('string') // resultAsert 值为 6let resultAsert2 = getMyTypeUnionAsert(100.1234) // resultAsert2 值为 100.12
但有时候你十分确定传入函数的变量的类型就是 string 或者 number,因此你并不想写 if else 来判断变量类型,这个时候可以使用类型断言,如:
function getMyTypeUnionAsertYes(myParam:string|number){ let newP =myParam return newP.length}// 或者function getMyTypeUnionAsertYes(myParam:string|number){ let newP = (myParam as string).length return (myParam as number).toFixed()}
七、Typescript中的类型别名
类型别名就是为类型取另外一个名字,使用 type 关键字来标示。
类型别名常见于联合类型,因为,联合类型有点长,你懂的,比如下面这个联合类型let unonType :string | number | boolean | object | (() => string)
类型别名这样定义:
type Name = string;type NameResolver = () => string;type NameOrResolver = Name | NameResolver;function getName(n: NameOrResolver): Name { if (typeof n === 'string') { return n; } else { return n(); }}
类型别名有时候可接口看起来有点像,比如:
这样定义了一个叫 aliasObj 类型别名type aliasObj = { name:string, age:number, getName:(age:number)=>{}}
这样定义了一个叫 interObj 接口
interface interObj { name:string, age:number, getName:(age:number)=>{}}
类型别名和接口同样都可以使用泛型(泛型后面的文章会详细讲解),如:
type tree= { value:T, key:T, other:number | string }interface car { wheel:T, speed:T,}
当然,类型别名和接口有区别,接口可以被 extends 和 implements ,类型别名不行
interface bus extends car{}// 这样会报错:type otherTree extends tree{}
八、Typescript中的枚举类型
枚举类型用来将取值限定在一定的范围之内,比如一周七天限定周一到周日分别用0至6的数字表示
1、枚举中若未明确赋值,枚举默认从0递增 可通过点语法或者键值对的方式取值enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};console.log(Days["Sun"] === 0); // trueconsole.log(Days["Mon"] === 1); // trueconsole.log(Days.Tue === 2); // trueconsole.log(Days.Fri === 6); // true
2、明确赋值时,从赋值位置递增
enum Days {Sun = 7, Mon = 1, Tue, Wed, Thu, Fri, Sat};console.log(Days.Sun) // 7console.log(Days.Mon) // 1console.log(Days.Sat) // 6
一个使用枚举的例子,通过枚举的属性来访问枚举成员,和枚举的名字来访问枚举类型
enum Response { No = 0, Yes = 1,}function respond(recipient: string, message: Response): void { // ...}respond("Princess Caroline", Response.Yes)
3、字符串枚举
需要注意,在一个字符串枚举中,每个成员都必须用字符串字面量,或另外一个字符串枚举成员进行初始化。enum Direction { Up = "UP", Down = "DOWN", Left = "LEFT", Right = "RIGHT",}
4、手动赋值的枚举项也可以为小数或负数,此时后续未手动赋值的项的递增步长仍为 1
enum Days {Sun = 7, Mon = 1.5, Tue, Wed, Thu, Fri, Sat};console.log(Days["Sun"] === 7); // trueconsole.log(Days["Mon"] === 1.5); // trueconsole.log(Days["Tue"] === 2.5); // trueconsole.log(Days["Sat"] === 6.5); // true
5、枚举的计算所得项
枚举值可由计算所得enum Color {Red, Green=1+2, Blue = "blue".length};
6、常量枚举
常量枚举 用 const 标示const enum Directions { Up, Down, Left, Right}let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right];
九、Typescript中的数组类型
数组类型的定义方式有多种方式
1、最简单的一种,类型+放括号,如:let numArr : number[] = [1,2,3] // numArr 数组内不能放其他类型的数据,比如字符串或者布尔值let objArr : Object[] = [ {}, function(){}, (p:string)=>{} ]// any 类型数组let anyArr : any[] = [ 1,'string', function(){}, false ]
2、使用数组泛型定义数组类型
let nArr : ArraynArr = [1,100,58]let aArr :Array
3、用接口来描述数组
interface NumberArray { [index: number]: number;}let fibonacci: NumberArray = [1, 1, 2, 3, 5];