一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情。
1. TypeScript中的配置文件
-
执行命令
tsc
则会按tsconfig中的配置来编译,如果是tsc xxx.ts
则不会按tsconfig中的配置来编译【执行ts-node xxx.ts
会按tsconfig中的配置来编译】 -
tsconfig.json中的配置项
- include/files:需要编译哪些
- exclude:哪些不需要编译
- compilerOptions中的编译配置项
- removeComments:是否去掉注释
- noImplicitAny:是否要求指定any(属性值为true的时候必须加any)
- strictNullChecks:是否强制检测null的类型
- rootDir:编译后生成文件的存放目录
- outDir:需要编译的文件目录
- incremental:是否开启增量式的编译(即只编译修改的那部分代码)
- target:编译后的代码版本
- allowJs:是否允许js文件也能在ts编译时进行编译转换到指定的es版本
- checkJs:是否允许对js代码进行语法检测(如同ts语法检测一样)
- sourceMap:是否生成
xxx.map
文件 - noUnusedLocals:是否开启对定义但未被使用的变量进行检测
- noUnusedParameters:是否开启对声明但未被使用的函数参数进行检测
具体用法参考官网:www.typescriptlang.org/docs/handbo…
2. 联合类型和类型保护
联合类型
-
联合类型采用
|
符号来连接不同的类型 -
联合类型的代码提示只会提示共有的变量和方法,其他的不会提示也不能使用。若要使用,可以采取类型保护的方法。
类型保护的四种方法
- 类型断言的方式
- 使用in 语法来做类型保护
- 使用typeof 语法来做类型保护
- 使用instanceof 语法来做类型保护
interface Bird {
fly: boolean;
sing: () => {};
}
interface Dog {
fly: boolean;
bark: () => {};
}
// 类型断言的方式
function trainAnial(animal: Bird | Dog) {
if(animal.fly) {
(animal as Bird).sing()
}else {
(animal as Dog).bark()
}
}
// 使用in 语法来做类型保护
function trainAnialSecond(animal: Bird | Dog) {
if('sing' in animal) {
animal.sing()
}else {
animal.bark()
}
}
// 使用typeof 语法来做类型保护
function add(first: string | number, second: string | number) {
if(typeof first === 'string' || typeof second === 'string') {
return `${first}${second}`
}
return first + second
}
// 使用instanceof 语法来做类型保护
class NumberObj {
count: number
}
function addSecond(first: object | NumberObj, second: object | NumberObj) {
if(first instanceof NumberObj && second instanceof NumberObj) {
return first.count + second.count
}
return 0
}
3. Enum 枚举类型
枚举类型一般用来做多个状态的条件判断,来使得代码的可读性增强
enum Status {
OFFLINE,
ONLINE,
DELETED
}
console.log(Status.OFFLINE, Status[0]); // 输出0 OFFLINE
// const Status = {
// OFFLINE: 0,
// ONLINE: 1,
// DELETED: 2
// }
// function getResult(status) {
// if (status === Status.OFFLINE) {
// return 'offline';
// } else if (status === Status.ONLINE) {
// return 'online';
// } else if (status === Status.DELETED) {
// return 'deleted';
// }
// return 'error';
// }
// const result = getResult(1);
// console.log(result);
默认值从0开始,也可以修改,如下
enum Status {
OFFLINE = 1,
ONLINE,
DELETED
}
console.log(Status.OFFLINE, Status[0]);// 输出为1 undefined(此时的Status[1]才是OFFLINE)
4. 函数泛型
泛型即泛指的类型
- 泛型声明:函数名后面用
<xx>
进行声明,然后参数和返回值都可以使用xx类型进行类型定义 - 泛型使用:函数调用时在函数名后面用面用
<具体类型>
显式声明类型 或者 使用ts的类型推断机制
// 泛型 generic
function join<T, P>(first: T, second: P) {
return `${first}${second}`;
}
function anotherJoin<T>(first: T, second: T): T {
return first;
}
// T[]
function map<T>(params: Array<T>) {
return params;
}
// join<number, string>(1, '1');
// map<string>(['123']);
join(1, '1'); // 也不会报错,因为ts会进行类型推断
5. 类中的泛型以及泛型类型
- 如果类中需要约束泛型必须有某个属性,如name: string,则可以用泛型来继承定义好的接口,如
<T extends Item>
- 如果类中需要约束泛型只能为特定类型,可以使用extends来继承类型。如
<T extends number | string>
该泛型表示必须拥有number或者string类型的相关属性。
// interface Item {
// name: string;
// }
// class DataManager<T extends number | string> {
// constructor(private data: T[]) {}
// getItem(index: number): T {
// return this.data[index];
// }
// }
// const data = new DataManager<number>([1]);
// data.getItem(0);
// const data = new DataManager([
// {
// name: 'dell'
// }
// ]);
// interface Test {
// name: string;
// }
// const data = new DataManager<number>([]); // 此时的泛型使用必须为number或者string或者拥有其中一种类型的所有相关属性,不能为Test
// 如何使用泛型作为一个具体的类型注解
function hello<T>(params: T) {
return params;
}
const func: <T>(param: T) => T = hello;