npm i typescript -g
tsconfig.json
{
"compilerOptions": {
"outDir": "./dist",
"target": "es5",
"watch": true
},
"include": ["./src/**/*"]
}
**
: 所有目录(包括子目录)*
: 所有文件,也可以指定类型 *.ts有了单独的配置文件,我们就可以直接编译执行
tsc
使用 --project
或 -p
指定配置文件目录,会默认加载该目录下的 tsconfig.json
文件,也可以直接指定配置文件
类型系统包含两个重要组成部分
在 TypeScript 中,类型标注的基本语法格式为:
数据载体:类型
TypeScript 的类型标注,我们可以分为
let title: string = '123';
let n: number = 100;
let isOk: boolean = true;
因为在 Null 和 Undefined 这两种类型有且只有一个值
在标注一个变量为 Null 和 Undefined 类型后,就表示该变量不能修改了
let a: null;
let b: undefined;
// 报错
a = 1;
b = 2;
但是可以将null/undefined
赋值给其他类型,因为是其他类型的子类型
let a: string;
let b: number;
a = null;
b = undefined;
如果一个变量声明了,但是未赋值,那么该变量的值为 undefined ,但是如果它同时也没有标注类型的话,默认类型为 any
因为 null 和 undefined 都是其它类型的子类型,所以默认情况下会有一些隐藏的问题
let a:number;
a = null;
// ok(但是实际运行是有问题的)
a.toFixed(1);
let ele = document.querySelector('div');
// 获取元素的方法返回的类型可能会包含 null,所以最好是先进行必要的判断,再进行操作
if (ele) {
ele.style.display = 'none';
}
可以通过对象的 构造函数 或者 类 来进行标注
let a: object = {};
let arr: Array<number> = [1,2,3];
let d1: Date = new Date();
let a: {username: string; age: number} = {
username: 'lc',
age: 35
};
// ok
a.username;
a.age;
// error
a.gender;
简单直接
但是不便于维护
interface Person {
username: string;
age: number;
};
let a: Person = {
username: 'zMouse',
age: 35
};
// ok
a.username;
a.age;
// error
a.gender;
优点 : 复用性高
缺点 : 接口只能作为类型标注使用,不能作为具体值,它只是一种抽象的结构定义,并不是实体,没有具体功能实现
class Person {
constructor(public username: string, public age: number) {
}
}
let a: Person = new Person("lc", 19);
// ok
a.username;
a.age;
// error
a.gender;
优点:功能相对强大,定义实体的同时也定义了对应的类型
缺点 : 复杂,比如只想约束某个函数接收的参数结构,没有必要去定一个类,使用接口会更加简单
interface AjaxOptions {
url: string;
method: string;
}
function ajax(options: AjaxOptions) { }
ajax({
url: '',
method: 'get'
});
包装对象其实就是 JavaScript 中的 String 、 Number 、 Boolean
string 类型 和 String 类型并不一样,在 TypeScript 中也是一样
let a: string;
a = '1';
a = new String('1');// error String有的,string不一定有(对象有的,基础类型不一定有)
let b: String;
b = new String('2');
// ok 和上面正好相反
b = '2';
泛型
let arr1: Array<number> = [];
// ok
arr1.push(100);
// error
arr1.push('lc');
简单标注
let arr2: string[] = [];
// ok
arr2.push('lc');
// error
arr2.push(1);
let data1: [string, number] = ['lc', 100];
// ok
data1.push(100);
// ok
data1.push('100');
// error
data1.push(true);
枚举的作用组织收集一组关联数据的方式,通过枚举我们可以给一组有关联意义的数据赋予一些友好的名字
推荐使用全大写(通常使用全大写的命名方式来标注值为常量)
注意事项:
enum HTTP_CODE {
OK = 200,
NOT_FOUND = 404,
METHOD_NOT_ALLOWED
};
// 200
HTTP_CODE.OK;
// 405
HTTP_CODE.METHOD_NOT_ALLOWED;
// error
HTTP_CODE.OK = 1;
如果前一个枚举值类型为字符串,则后续枚举项必须手动赋值
enum URLS {
USER_REGISTER = '/user/register',
USER_LOGIN = '/user/login',
// 如果前一个枚举值类型为字符串,则后续枚举项必须手动赋值
INDEX = 0
}
function add(x: number, y: number): number {
return x + y;
}
表示没有任何数据的类型,通常用于标注无返回值函数的返回值类型,函数默认标注类型为: void
strictNullChecks
为 false 的情况下, undefined 和 null 都可以赋值给 voidstrictNullChecks
为 true 的情况下,只有 undefined 才可以赋值给 voidfunction fn(): void {
// 没有 return 或者 return undefined
}
function fn(): never {
throw new Error('error');
}
有的时候,我们并不确定这个值到底是什么类型或者不需要对该值进行类型检测,就可以标注为 any类型
let a: any;
unknow,3.0 版本中新增,属于安全版的 any,但是与 any 不同的是:
let c: any = "123";
let d: number;
d = c;
// 实际运行时才会出错
d.toFixed(1);
unkown
let c: unknown = "123";
let d: number;
d = c;
// 编译时就会出错
d.toFixed(1);
比any更严格
let c: any;
c.a
let d: unknown;
d.a;