ts常用类型及基本概念
基本数据类型
js 类型分两种,基本数据类型(primitive data types)和对象类型(object types), 这里除了介绍js的5中基本数据类型外,还将介绍ts新增的void, any 等 , (js新增的两种基本类型 symbol (ES2015), bigint (ES2019) 这里暂不介绍)
boolean
let isOk: boolean = falselet createdBoolean: boolean = new Boolean(1) // Error// typeof new Boolean(1) is 'object'// typeof Boolean(false) is 'boolean'// 类似的可以new的还有 String, Number// Symbol、BigInt 没有new 构造函数
number
let decLiteral: number = 6;let hexLiteral: number = 0xf00d;// ES6 中的二进制表示法let binaryLiteral: number = 0b1010;// ES6 中的八进制表示法let octalLiteral: number = 0o744;let notANumber: number = NaN;let infinityNumber: number = Infinity;// 编译后,不同的是 二进制、八进制 会被编译为10进制// let 也会转为 varvar decLiteral = 6;var hexLiteral = 0xf00d;// ES6 中的二进制表示法var binaryLiteral = 10;// ES6 中的八进制表示法var octalLiteral = 484;var notANumber = NaN;var infinityNumber = Infinity;
string
let name: string = 'Tom'let str: string = `Hello, ${name}`// tsc 编译后var namestr = 'Tom';var str = "Hello, " + namestr;
null 与 undefined
默认情况下,null 和 undefined是所有类型的子类型,也就是可以将null或undefined赋值给number、string等类型的变量
let u: undefined = undefinedlet n: null = nulllet num2: string = null// 转换后var u = undefinedvar n = nullvar num2 = null
然而,当你指定了—strictNullChecks标记,null和undefined只能赋值给void和它们各自。 这能避免很多常见的问题。 也许在某处你想传入一个string或null或undefined,你可以使用联合类型string | null | undefined。 再次说明,稍后我们会介绍联合类型。 注意:我们鼓励尽可能地使用—strictNullChecks,但在本手册里我们假设这个标记是关闭的。
数组: Array<类型> 或 类型[]
ts有两种方式定义数组:
元素类型后面接上[]
let list: number[] = [1, 2, 3]// var list = [1, 2, 3];
使用数组泛型
uses a generic array type, Array
泛型(Generic)所操作的数据类型被指定为一个参数
let list2: Array<number> = [1, 2, 3]// var list2 = [1, 2, 3];
元组 tuple
tuple,也是一个数组,且已知数组长度,以及每个元素的类型,每个元素类型可以不一致
// Declare a tuple type 声明一个元组类型let x: [string, number];// Initialize itx = ['hello', 10]; // OK// Initialize it incorrectly 错误的初始化x = [10, 'hello']; // Error// 当访问越界的元素,会使用联合类型代替(后面后讲到)x[3] = 'world'; // OK, 字符串可以赋值给(string | number)类型console.log(x[5].toString()); // OK, 'string' 和 'number' 都有 toStringx[6] = true; // Error, 布尔不是(string | number)类型
枚举 enum
枚举类型可以为一组数值赋予友好的名字
enum Color {Red, Green, Blue} // 默认从0开始为元素编号let c: Color = Color.Green; // 获取该枚举的索引值let colorName: string = Color[2]; // 获取枚举字符串console.log(c, colorName) // 1 'Blue'// 编译为var Color;(function (Color) {Color[Color["Red"] = 0] = "Red";Color[Color["Green"] = 1] = "Green";Color[Color["Blue"] = 2] = "Blue";})(Color || (Color = {})); // 默认从0开始为元素编号var c = Color.Green;var colorName = Color[2];console.log(c, colorName);// 可以改变开始索引enum Color {Red = 1, Green, Blue}let c: Color = Color.Green;// 也可以全部索引手动赋值enum Color { Red = 1, Green = 2, Blue = 4}let c: Color = Color.Green
any 任意值
let notSure: any = 4notSure = "maybe a string instead";notSure = false; // okay, definitely a boolean// 数组元素类型为anylet list: any[] = [1, true, "free"];list[1] = 100;
void 空值
与any类型相反,它表示没有任何类型。一般用于没有任何返回值的函数,void类型只能赋值为 null 或undefined,不能将void类型的值赋值给 number 等
function alertName(): void {alert('My name is Tom')}// 单独声明一个void类型没有什么用处,只能赋值为 undefined或nulllet unusable: void = undefinedunusable = null; // OK if `--strictNullChecks` is not givenlet u: void = undefinedlet num: number = u // Error
never
never类型
- 总是会抛出异常
- 根本就不会有返回值的函数表达式
- 箭头函数表达式的返回值类型
// 返回never的函数必须存在无法达到的终点function error(message: string): never {throw new Error(message);}// 推断的返回值类型为neverfunction fail() {return error("Something failed");}// 返回never的函数必须存在无法达到的终点function infiniteLoop(): never {while (true) {}}
object
object表示非原始类型,也就是除number,string,boolean,symbol,bigint, null或undefined之外的类型。
使用object类型,就可以更好的表示像Object.create这样的API。例如:
declare function create(o: object | null): void;create({ prop: 0 }); // OKcreate(null); // OKcreate(42); // Errorcreate("string"); // Errorcreate(false); // Errorcreate(undefined); // Error
类型断言(Type assertions)
通过类型断言这种方式可以告诉编译器,“相信我,我知道自己在干什么”。 类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。 它没有运行时的影响,只是在编译阶段起作用。 TypeScript会假设你,程序员,已经进行了必须的检查。
一句话解释:手动指定一个值的类型。
Type assertions have two forms. 当在TypeScript里使用JSX时,只有as语法断言是被允许的。
“angle-bracket” syntax (‘尖括号’语法)
let someValue: any = 'this is a string'let strLength: number = (<string>someValue).length
as syntax(as语法)
let someValue: any = "this is a string";let strLength: number = (someValue as string).length;
关于let
不推荐使用var, 很多常见的问题都可以通过使用let来解决, 尽可能地使用let来代替var
ts官网用了一个章节(变量声明)来讲let和var,这些是js基础,所以这里不讨论,可以参考: TypeScript - Variable Declarations
类型推论
声明变量时如果没有指定类型,那ts会依照类型推论(Type Inference)的规则来推断出一个类型,如果声明时没有赋值,不管之后有没有赋值,都会被推断为 any类型
let testNumber = 'six' // 这里会根据值的类型,推断出testNumber为stringtestNumber = 6 // Error// 声明时不赋值let testNumber; // 等价于 let testNumber: anytestNumber = 'six'testNumber = 6
联合类型(Union Types)
联合类型,表示值可以为多种类型中的一种,以 | 分隔
let myNumber: string | numbermyNumber = 'six'myNumber = 6
访问联合类型的属性和方法
当不确定联合类型到底是哪个类型时,只能访问此联合类型的所有类型里共有的属性或方法
function fun(myNumber: string | number): number {console.log(myNumber.length) // Errorconsole.log(myNumber.toString()) // OK}
联合类型的变量赋值时类型推断
联合类型的变量在被赋值的时候,会根据类型推论的规则推断出一个类型
let myNumber = myNumber: string | numbermyNumber = 'six' // myNumber被推断为 string 类型console.log(myNumber.length) // OKmyNumber = 6 // myNumber被推断为 number 类型console.log(myNumber.length) // Error
