Typescript 实战 --- (1)数据类型
1、强类型语言与弱类型语言
(1)、强类型语言
通俗定义:强类型语言不允许改变变量的数据类型,除非进行强制类型转换
在强类型语言中,当一个对象从调用函数传递到被调用函数时,其类型必须与被调用函数中声明的类型兼容
(2)、弱类型语言
在弱类型语言中,变量可以被赋予不同的数据类型
let x = 1; x = 'hello'; console.log(x); // hello x = true; console.log(x); // true
2、静态类型语言和动态类型语言
(1)、静态类型语言
在编译阶段确定所有变量的类型
(2)、动态类型语言
在执行阶段确定所有变量的类型
静态类型与动态类型的对比:
语言类型象限:
3、数据类型
类型注解
作用:相当于强类型语言中的类型声明,可以对变量起到约束作用
语法:(变量/函数): type
let checkAll: boolean = false; checkAll = true; console.log('checkAll ', checkAll); // checkAll true checkAll = null; console.log('checkAll ', checkAll); // checkAll null checkAll = undefined; console.log('checkAll ', checkAll); // checkAll undefined // 类型注解使得 ts 的变量数据类型不可随意改变 checkAll = 'hello'; // 不能将类型“"hello"”分配给类型“boolean” checkAll = 123; // 不能将类型“123”分配给类型“boolean” checkAll = [1, 2]; // 不能将类型“number[]”分配给类型“boolean”
TypeScript 在 ES6的基础之上新增了一些数据类型
3-1、布尔值 - boolean
let isDone: boolean = false;
3-2、数字 - number
let decLiteral: number = 6; // 十进制 let hexLiteral: number = 0xf00d; // 十六进制 let binaryLiteral: number = 0b1010; // 二进制 let octalLiteral: number = 0o744; // 八进制
3-3、字符串 - string
let str1: string = 'hello'; // 单引号 let str2: string = "world"; // 双引号 let str: string = `${str1} ${str2} !`; // 摸板字符串 console.log(str); // hello world !
3-4、数组 - Array
// 定义方式一:type[],表示由此类型元素组成的一个数组 let list: number[] = [1, 2, 3]; // 定义方式二:Array<type>,使用数组泛型 let result: Array<number> = [1, 2, 3]; // 数组一旦在定义时指定了数据类型,就不能添加其它的数据类型 list.push('hello'); // 类型“"hello"”的参数不能赋给类型“number”的参数 // 如果想要一个数组接收两种数据类型,可以这么做 let data: Array<number | string> = [1, 'hello', 2, 'world'];
3-5、元组 - Tuple
元组类型表示一个已知元素数量和类型的数组,准确的说,是已知数组中的每一个位置上的元素类型
为元组类型赋值时,各个位置上的元素类型都要对应,元素个数也要一致
let tuple: [string, number] = ['Bob', 23]; tuple = ['Bob', 'Chirs']; // 不能将类型“string”分配给类型“number” tuple = [23, 32]; // 不能将类型“number”分配给类型“string” tuple = ['Bob', 23, 32]; // 不能将类型“[string, number, number]”分配给类型“[string, number]”
强烈不建议像数组一样添加、删除和修改元组的元素
let tuple: [number, string] = [0, '1']; tuple.push(1); console.log('tuple', tuple); // tuple [ 0, '1', 1 ] // 试图读取越界元素时,还是会报错 tuple[2]; // Tuple type '[number, string]' of length '2' has no element at index '2'
3-6、函数
let add = (x: number, y: number): number => x + y // 根据函数的类型推断功能,可以简写为 let add = (x: number, y: number) => x + y // 定义函数类型 let getResult: (x: number, y: number) => number // 实现函数(参数名不必相同,也无需指出参数类型、函数返回值) getResult = (a, b) => a + b
3-7、对象
let obj: {name: string, age: number} = { name: 'Bob', age: 23 } obj.age = 30; console.log('obj', obj); // obj { name: 'Bob', age: 30 } // 如果不具体指出对象的参数类型,则无法修改对象的属性 let map: object = {x: 1, y: 2}; map.x = 22; // 类型“object”上不存在属性“x”
3-8、Symbol
具有唯一的值
// symbol 类型的值是通过 Symbol 构造函数创建的 let s1: symbol = Symbol(); let s2 = Symbol(); console.log(s1 === s2); // false, symbols是唯一的
3-9、undefined 和 null
如果一个变量被初始化为 undefined 或 null,就不能再赋值其它数据类型
let un: undefined = undefined; let nu: null = null; un = 12; // 不能将类型“12”分配给类型“undefined” nu = 34; // 不能将类型“34”分配给类型“null”
默认情况下,undefined 和 null 是所有类型的子类型,也就是说可以把 undefined 和 null 赋值给 number、string 等类型的变量
let num: number = 23; num = undefined; let str: string = 'hello'; str = null; let bool: boolean = false; bool = undefined;
3-10、void
void 是一种操作符,表示没有任何返回值的类型,它可以让任意一个表达式返回undefined
function warnUser(): void { alert("This is my warning message"); }
3-11、any
如果不指定一个变量的类型,则默认就是any类型
let x; x = 1; x = {}; x = () => {}
3-12、never
never表示永远不会有返回值的类型,有两种情况:
(1)、函数抛出异常
(2)、死循环
let error = () => { throw new Error('error') } let endless = () => { while(true) {} }