开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 7 天,点击查看活动详情
编程实际上就是对数据进行操作和加工的过程。类型系统能辅助我们对数据进行更为准确的操作。TypeScript 的核心就在于其提供一套类型系统,让我们对数据类型有所约束。约束有时候很简单,有时候很抽象。
TS 支持的类型如下:
boolean,number,string,[],Tuple,enum,any,void,null,undefined,never,Object。 TS 中更复杂的数据结构其实都是针对上述类型的组合
0. 官方文档以及综述
devblogs.microsoft.com/typescript/
TypeScript 概述 - Training | Microsoft Learn
JavaScript 是解释型语言,没有编译阶段,所以它是动态类型的语言。动态类型的语言是指在运行时才会进行类型检查的语言,这种语言的类型错误往往会导致运行时错误。
TypeScript 在运行前需要先编译为 JavaScript,而在编译阶段就会进行类型检查,所以 TypeScript 是静态类型。静态类型是指编译阶段就能确定每个变量的类型,这种语言的类型错误往往会导致语法错误。
1. 安装-编译
```
npm install -g typescript // 全局安装
tsc hello.ts // 编译
node hello.js // 执行
```
VSCode安装插件Code Runner,右键Run Code 即可
2. 字符串
let myName: string = 'Tom';
let myAge: number = 25;
// 模板字符串
let sentence: string = `Hello, my name is ${myName}.
I'll be ${myAge + 1} years old next month.`;
其中 ` 用来定义 ES6 中的模板字符串,${expr} 用来在模板字符串中嵌入表达式
编译后:
var myName = 'Tom';
var myAge = 25;
// 模板字符串
var sentence = "Hello, my name is " + myName + ".
I'll be " + (myAge + 1) + " years old next month.";
3. 接口
我们定义了一个接口 Person,接着定义了一个变量 tom,(tom对象),它的类型是 Person。这样,我们就约束了 tom 的形状必须和接口 Person 一致,即定义的变量比接口少一些属性或多一些属性都是不允许的。
interface Person {
name: string;
age: number;
}
let tom: Person = {
name: 'Tom',
age: 25
};
可选属性,age?:number;
tom(tom对象)可以不定义该属性
可选属性的含义是该属性可以不存在
任意属性,[propName: string]: any; (任意属性,任意取个名字的属性)
使用 [propName: string] 定义了任意属性取 string 类型的值
任意属性的类型为string时,那么确定属性和可选属性的类型都必须为它的类型的子集。此时,接口中其它属性必须也是string类型。
使用:gender:'male' 接口中无gender属性, 一个接口中只能定义一个任意属性。
如果接口中有多个类型的属性,则可以在任意属性中使用联合类型 [propName: string]: string | number; // 联合类型(Union Types)表示取值可以为多种类型中的一种
只读属性 readonly id: number;
对象初始化后,该属性不能二次赋值
4. 数组
// 类型 + 方括号 表示数组
let fibonacci: number[] = [1,1,2,3,5];
// 泛型 表示数组
let fibonacci: Array<number> = [1,1,2,3,5];
// 接口表示数组
interface NumberArray {
[index:number]:number;
}
let fionacci:NumberArray = [1,1,2,3,5];
// 类数组
function sum(){
let args:{
[index:number]:number;
length:number;
callee:Function;
} = arguments;
}
function sum(){
let args:IArguments = arguments; // 其中 IArguments 是 TypeScript 中定义好了的类型
}
// any 在数组中的应用 用 any 表示数组中允许出现任意类型
let list: any[] = ['xiaoming',25,{websit:'www.xiaoming.com'}];
5. 函数
// javascript中两种定义函数的方式
// 方式一 函数声明
function sum(x,y){
return x + y;
}
// 方式二 函数表达式
let mySum = fuction(x,y){
return x + y;
} ; // ;
一个函数有输入和输出,要在 TypeScript 中对其进行约束,需要把输入和输出都考虑到
函数声明
function sum(x:number,y:number):number{
return x + y;
}
函数表达式
let mySum : (x:number,y:number) => number =
function (x:number,y:number) : number {
return x + y;
};
TypeScript 中的 => 用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型。
(x:number,y:number) => number
用接口定义函数的形状
我们也可以使用接口的方式来定义一个函数需要符合的形状
interface SearchFunc {
(source:string,subString:string):boolean;
}
let mySearch: SearchFunc;
mySearch = function(source:string,substring:string){
return source.serarch(subString) !== -1;
}
函数参数
// 可选参数 param?:string 可选参数后面不允许再出现必需参数
function buildName(firstName: string, lastName?: string)
// 参数默认值 TypeScript会将添加默认值的参数识别为可选参数
param:string = 'defaultValue'
剩余参数 ...rest 获取函数中的剩余参数
6. 内置对象
ECMAScript标准提供的内置对象有:Boolean、Error、Date、RegExp等,我们可以在TypeScript中将变量定义为这些类型。
let b:Boolean = new Boolean(1);
let e:Error = new Error('Error occurred');
let d:Date = new Date();
let r:RegExp = /[a-z]/;
DOM和BOM提供的内置对象有:Document、HTMLElement、Event、NodeList等
let body:HTMLElement = document.body;
let allDiv:NodeList = document.querySelectorAll('div');
document.addEventListener('click',function(e:MouseEvent){
// TODO
});
7. 类型别名
用来给一个类型起一个新名字。类型别名常用于联合类型。
type Name = string;
type NameResolver = ()=>string;
type NameOrResolver = Name | NameResolver;
function getName(n:NameOrResolver):Name{
if (typeof n === 'string'){
return n;
} else {
return n();
}
}
字符串字面量类型
用来约束取值只能是某几个字符串中的一个
type EventNames = 'click' | 'scroll' | 'mousemove';
function handleEvent(ele: Element, event: EventNames) {
// do something
}
handleEvent(document.getElementById('hello'), 'scroll'); // 没问题
handleEvent(document.getElementById('world'), 'dblclick'); // 报错,event 不能为 'dblclick'
// index.ts(7,47): error TS2345: Argument of type '"dblclick"' is not assignable to parameter of type 'EventNames'.
这个例子中,我们使用type定义了一个字符串字面量类型 EventNames,它只能取三种字符串中的一种。注意:类型别名与字符串字面量类型都是使用type进行定义。
8. 元组 Tuple
数组合并相同类型的对象,元组合并不同类型的对象。元组起源于函数编程语言。
// 定义一对值分别为 string 和 number的元组
let tom: [string,number] = ['Tom',25];
// 赋值或访问
let tom:[string,number];
tom[0] = 'Tom';
tom[1] = 25;
tom[0].slice(1);
tom[1].toFixed(2);
9. 枚举 enum
enum Days {Sun,Mon,Tue,Wed,Thu,Fri,Sat};
// 枚举成员会被赋值为从0开始递增的数字,同时也会对枚举值到枚举名进行反向映射
console.log(Days["Sun"] === 0); // true
console.log(Days["Mon"] === 1); // true
console.log(Days["Tue"] === 2); // true
console.log(Days["Sat"] === 6); // true
console.log(Days[0] === "Sun"); // true
console.log(Days[1] === "Mon"); // true
console.log(Days[2] === "Tue"); // true
console.log(Days[6] === "Sat"); // true
// 手动赋值
enum Days {Sun = 7, Mon = 1, Tue, Wed, Thu, Fri, Sat};
console.log(Days["Sun"] === 7); // true
console.log(Days["Mon"] === 1); // true
console.log(Days["Tue"] === 2); // true
console.log(Days["Sat"] === 6); // true
// 未手动赋值的枚举项会接着上一个枚举项递增。
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 7 天,点击查看活动详情