1. Typescript.json 配置文件 tsconfig.json 包含的属性不多,只有 7 个。 官方还给出了它的定义文件,如下图: 如果不设置 files 和 include,ts 默认为 except 以外的所有文件以 .ts 和 .tsx 结尾。 如果同时设置文件的优先级最高,排除次之,包含最低。 都是和文件相关的,和编译相关的都是通过compilerOptions来设置的。 代码如下:
{
"compilerOptions": {
// "incremental": true, // 增置编译
// "tsBuildlnfoFile": "./buildFile", // 增置编译文件的存储位置 // "diagnostics": true, // 打印诊断倍息
// "target": "es5", // 目标语言的版本
// "module": "commonjs", // 生成代码的模块标准
// "outFile": "./app-js", // 将多个相互依赖的文件生成一个文件,可以用在AMD模块中
// "lib": [], // TS 需要引用的库,即声明文件,es5 默认"dom", "es5", "scripthost"
// "allowJs": true, // 允许编译:IS 文件(js、jsx)
// "checkJs": true, // 允许在JS文件中报错,通常与allowJS _起使用
// "outDir": "./dist", // 指定输出目录
// "rootDir": "./", // 指定输入文件目录(用于输出)
// "declaration": true, // 生成声明文件
// "declarationDir": "./d", // 声明文件的路径
// "emitDeclarationOnly": true, // 只生成声明文件
// "sourceMap": true, // 生成目标文件的 sourceMap
// "inlineSourceMap": true, // 生成目标文件的 inline sourceMap
// "declarationMap": true, // 生成声明文件的 sourceMap
// "typeRoots":[], // 声明文件目录,默认node_modules/@types
// "types":[], // 声明文件包
// "removeComments":true, // 删除注释
// "noEmit": true, // 不输出文件
// "noEmitOnError": true, // 发生错误时不输出文件
// "noEmitHelpers": true, // 不生成helper 函数,需要额外安装ts-helpers
// "importHelpers": true, // 通过tslib 引入 helper 函数,文件必须是模块
// unoEmitOnErrorM: true, // 发生错误时不输出文件
// "noEmitHelpers": true, // 不生成 helper 函数,需额外安装 ts-helpers
// "importHelpers": true, // 通过tslib引入helper函数,文件必须是模块
// "downlevellteration" : true, // 降级遍历器的实现(es3/5)
// "strict": true, // 开启所有严格的类型检查
// "alwaysStrict": false, // 在代码中注入"use strict";
// "noImplicitAny": false, // 不允许隐式的any类型
// "strictNullChecksilj false, // 不允许把null、undefined赋值给其他类型变置
// "strictFunctionTypes": false, // 不允许函数参数双向协变
// "strictPropertyInitialization": false, // 类的实例属性必须初始化
// strictBindCallApply: false, // 严格的 bind/call/apply 检査
// "noImplicitThis": false, // 不允许this有隐式的any类型
// "noUnusedLocals": true, // 检査只声明,未使用的局部变置
// "nollnusedParameters": true, // 检查未使用的函数参数
// "noFallthroughCasesInSwitch": true, // 防止switch语句贯穿
// "noImplicitReturns": true, // 每个分支都要有返回值
// "esModulelnterop": true, // 允许export = 导出,由import from导入
// "allowUrndGlobalAccess": true, // 允许在模块中访问UMD全局变置
// "moduleResolution": "node", // 模块解析策略
// "baseUrl": "./", // 解析非相对模块的基地址
// "paths": {
// "jquery": ["node-modules/jquery/dist/jquery.slim.min.js"]
// }
// "rootDirs": ["src", "out"], // 将多个目录放在一个虚拟目录下,用于运行时
// "listEmittedFiles": true, // 打印输出的文件
// "listFiles": true, // 打印编译的文件(包括引用的声明文件)
},
// "include": [ // 指定一个匹配列表(属于自动指定该路径下的所有ts相关文件)
// "src/**/*.ts",
// "src/**/*.tsx",
// "src/**/*.vue",
// "tests/**/*.ts",
// "tests/**/*.tsx"
// ],
// "exclude": [ // 指定一个排除列表(include的反向操作)
// "node_modules"
// ],
// "files": [ // 指定哪些文件使用该配置(属于手动一个个指定文件)
// "demo.ts"
// ]
}
tsconfig.app.json,代码如下:
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"types": [] // https://stackoverflow.com/questions/39826848/typescript-2-0-types-field-in-tsconfig-json
},
// 需要编译的文件
"files": [
"src/main.ts",
"src/polyfills.ts"
],
// 需要编译的文件
// files 和 include 两个属性的组合定义了所有要编译的文件
"include": [
"src/**/*.ts"
],
// 不需要编译的
"exclude": [
"src/test.ts",
"src/**/*.spec.ts"
]
}
2、Typescript的类型高级联合类型与交叉类型非常相关,但用法却完全不同。 联合类型表明一个值可以是多种类型之一。 我们用竖线 (|) 分隔每种类型,因此 number|string|boolean 表示值可以是数字、字符串或布尔值。 如果一个值是联合类型,我们只能访问该联合类型的所有类型所共有的成员。 联合类型适用于值可以是不同类型的情况,而区分 2 个可能值之间的差异的方法是检查成员是否存在。 TypeScript 中的类型保护机制是一些表达式,这些表达式将在运行时检查以确保类型在一定范围内。 类型防护还可以解决联合类型、不规则句子模式等中潜在的类型问题。 对于类型保护,有如下几种情况: 对于联合类型和类型保护代码,如下:
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();
}
}
function trainAnialSecond(animal: Bird | Dog) {
if ("sing" in animal) {
animal.sing();
} else {
animal.bark();
}
}
function add(first: string | number, second: string | number) {
if (typeof first === "string" || typeof second === "string") {
return `${first}${second}`;
}
return first + second;
}
class NumberObj {
count: number;
}
function addSecond(first: Object | NumberObj, second: Object | NumberObj) {
if (first instanceof NumberObj && second instanceof NumberObj) {
return first.count + second.count;
} else {
return 0;
}
}
枚举,使用枚举typescript定义注解,我们可以用名称来定义一些常量,使用枚举来清楚地表达意图或者创建一组差异化的用例,TypeScript 支持数字和基于字符串的枚举。 使用枚举通过枚举属性访问枚举成员,使用枚举名称访问枚举类型。 枚举类型如下:文字枚举成员、常量枚举成员的特殊非计算子集、没有初始值的常量枚举成员、或初始化为任何字符串文字的值、任何数字文字以及一元 - 应用表示法。 当所有枚举成员都具有文字枚举值时,枚举成员将成为类型,并且枚举类型本身将成为每个枚举成员的并集。 enum枚举默认值为0,前面递归加1,所以输出值为012。如果更改该值,将ONLINE设置为4,所以输出值为045。另外创建对象以属性名作为对象成员,数值枚举成员也有反向映射,从枚举值到枚举名,代码如下:
enum Status {
OFFLINE,
ONLINE,
DELETED,
}
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";
}
console.log(getResult(Status.OFFLINE));
3、Typescript的子类高级组件不仅可以支持当前的数据类型,还可以支持未来的数据类型,这为你在创建小型系统时提供了非常灵活的功能,同时也考虑到了可重用性。 使用子类来创建可重用的组件。 一个组件可以支持多种数据类型,这样用户就可以使用自己的数据类型的组件。 类库可以应用于多种类型。 类库函数之后,可以通过两种方式使用。 第一个是传入所有参数,包括类型参数。 第二种采用类型推断,即编译器会根据传入的参数手动帮我们判断T的类型。类库也可以理解为类型。 在连接中接收类型 T。 T是一个类库,可以是任意类型,如String、Number等,并指定first和second为T的子类。 使用join时,指定T类库为number类型,所以上面所有的参数也必须是number类型,否则会报错。 不仅参数可以使用类库T,返回结果中也可以使用类库T。 Map中接收类库T,params是一个链表。 上面接收到了类库T,Array和T[]是等价的。 使用map时,接收类库是字符串类型,上面的链表也必须是字符串类型。 在类库中typescript定义注解,不仅可以编写单个类库,还可以编写多个基类,为参数指定不同类型。 如果没有写入类型匹配,TS就会进行类型推断,代码如下:
function join<T>(first: T, second: T) {
return `${first}${second}`;
}
join<number>(1, 1);
function authjoin<T>(first: T, second: T): T {
return first;
}
authjoin(1, 2);
function map<T>(params: Array<T>) {
return params;
}
map<String>(["123"]);
function add<T, P>(first: T, second: P) {
return `${first}${second}`;
}
add<number, string>(1, "2");
库类看起来与库套接字类似。 类库类使用 () 将类库类型括起来,后跟类名。 类有两部分:静态部分和实例部分,子类类引用的是实例部分的类型,因此类的静态属性不能使用该类库类型。 类库约束,只要传入的类型有这个属性,我们就允许,也就是说,至少包含这个属性,就必须有约束。 定义一个套接字来描述约束,使用该接口和extends关键字来实现约束。 我们需要传入一个符合约束类型的值,并且必须包含必要的属性。 在子类中使用类类型。 TypeScript使用子类创建鞋工厂函数时,需要引用构造函数的类类型,并使用prototype属性来计算和约束构造函数与类实例之间的关系。 使用类库中的类,T继承了socket Item,用于Item的属性名。 构造函数将data约束为私有属性,链表,value为上面T的子类,并约束name为字符串类型。 使用类时,创建对象并使用子类。 在类基类中,您还可以使用联合类库。 使用类库也可以作为具体类型注解,代码如下:
interface Item {
name: string;
}
class DataManager<T extends Item> {
constructor(private data: T[]) {}
getItem(index: number): string {
return this.data[index].name;
}
}
const data = new DataManager([{ name: "Tom" }]);
class DataManager2<T extends number | String> {
constructor(private data: T[]) {}
getItem(index: number): T {
return this.data[index];
}
}
function hello<T>(params: T) {
return params;
}
const func: <T>(param: T) => T = hello;