1、泛型
Ⅰ. 泛型优化
// 常规写法:
function setNum(a:number,b:number):Array<number> {
return [a,b]
}
function setStr(a:string,b:string):Array<string> {
return [a,b]
}
// 利用泛型优化
// 函数名<T>
function setTypeData<T>(a: T, b:T):Array<T> {
return [a,b]
}
const generic_num = setTypeData<number>(1,2)
const generic_boolean = setTypeData(true,false)
Ⅱ. type
type Generic_Type<T> = number | string | T
let gen_A: Generic_Type<boolean> = 123
let gen_B: Generic_Type<boolean> = 'AAA'
let gen_C: Generic_Type<boolean> = true
Ⅲ. interface, 泛型接口
interface Gen_data<T> {
msg: T
}
let gen_data1: Gen_data<number> = {
msg: 1008611
}
Ⅳ. 定义多个泛型
function setGenData<T,K>(a: T,b:K) :Array<T | K>{
return [a,b]
}
let gen_data2 = setGenData(1,false)
Ⅴ. 示例接口封装
// 实用场景:接口调用。
const gen_axios = {
get<T>(url:string):Promise<T> {
return new Promise((resolve,reject) => {
let xhr:XMLHttpRequest = new XMLHttpRequest();
xhr.open('GET',url);
xhr.onreadystatechange = () => {
if(xhr.readyState == 4 && xhr.status == 200) {
resolve(JSON.parse(xhr.responseText))
}
}
xhr.send(null)
})
}
}
interface Gen_ax {
code: number,
message: string,
data: object
}
gen_axios.get<Gen_ax>('./data.json')
.then(res => {
console.log(res,'gen_axios')
})
注:ts无法识别XMLHttpRequest,需编译成js文件再运行。
2、泛型约束 keyof
Ⅰ. extends + 约束类型
// 泛型支持相加 || 获取length
function gen_add<T extends number>(a: T, b: T) {
return a + b;
}
gen_add(1, 1);
interface Len {
length: number;
}
function gen_len<T extends Len>(a: T) {
return a.length;
}
gen_len("112233");
gen_len([1, 2, 3]);
// gen_len(112233)
Ⅱ. 使用keyof约束对象
// 定义T类型并使用extend关键字继承object类型的子类型,
// 然后使用keyof操作符获取T类型的所有键(K extends keyof T)
let gen_obj = {
attack: 300,
mana: "none",
defense: "loading",
};
// keyof: 将对象的key推断为联合类型
type obj_typeof = typeof gen_obj; // 对象类型
type obj_keyof = keyof typeof gen_obj; //
function get_gen_obj<T extends object, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
get_gen_obj(gen_obj, "attack");
// get_gen_obj(gen_obj,'age') // 报错
Ⅲ.keyof 高级用法
interface gen_In {
name: string;
age: number;
sex: string;
}
// keyof 实现 for in
type gen_option<T extends object> = {
[Key in keyof T]?: T[Key];
};
type gen_Ex = gen_option<gen_In>;
Ⅳ. 泛型类
class Gen_Class<T> {
attr: T[] = [];
add(a: T): T[] {
return [a];
}
}
let gen_class1 = new Gen_Class<number>();
gen_class1.attr = [2,3,3,3];
gen_class1.add(133)
let gen_class2 = new Gen_Class<string>();
gen_class2.attr = ['2','2','3']
gen_class2.add('loading')
3、tsconfig.json
// 生成tsconfig.json文件
tsc --init
4、namespace 命名空间
ts 提供namespace为命名冲突的一种解决方案
Ⅰ. export || namespace
通过export暴露,namespace关键字定义。
export const a = '123'
namespace A {
export const a = 1008611
export const time: number = 10010;
}
console.log(a);
console.log(A.a);
Ⅱ. 嵌套命名空间
namespace B {
export const time: number = 1835;
export namespace C {
export const time: number = 3333
}
}
console.log(A.time)
console.log(B.time)
console.log(B.C.time)
Ⅲ. 抽离命名空间
import { B } from './index.ts'
console.log(B.time)
Ⅳ. 简化命名空间
import X = B.C.time;
console.log(X,'X')
Ⅴ. 合并命名空间
// 重复再合并,同interface
namespace AA {
export const b: string = 'AA.b';
}
namespace AA {
export const c:string = 'AA.c'
}
console.log(AA.b);
console.log(AA.c);
Ⅵ. 命名空间的案例
应用场景:跨端项目调用不同平台的能力,如:h5 android 小程序等。
namespace ios {
export const pushNotification = (msg: string, type: number) => {};
}
namespace android {
export const pushNotification = (msg: string ) => {}
export const callPhone = (phone: number) => {}
}
namespace miniProgram {
export const pushNotification = (msg: string) => {}
}
5、三斜线指令
包含单个XML标签的单行注释,注释的内容会做为编译器指令使用。
// Ⅰ. 引入额外的文件
///<reference path="9 class.ts"/>
// Ⅱ. 引入声明文件
// npm i @types/node
// ///<reference type="node" />
示例:index.ts 引入其他ts文件
namespace A {
// export const fn1 = () => 'fn1'
export const fn1 = 'fn1'
}
///<reference path="index2.ts"/>
///<reference path="index3.ts"/>
console.log(A)
console.log(A.fn1);
console.log(A.fn2);
console.log(A.fn3);
// 引入声明文件
///<reference type="node"/>
namespace A {
export const fn2 = () => 'fn2'
}
namespace A {
export const fn3 = () => 'fn3'
}
6、模块解析
在ES6模块化规范前,存在4种模块化解析方式,分别为
// ES6模块化规范之前
// 1、 Commonjs => Nodejs
// 导出
exports.xxx = function() {}
module.exports = xxx
// 导入
require('xxx')
require('../xxx.js')
// 2、AMD => requireJS
// 定义
// define("module",["dep1","dep2"], function(d1,d2){})
// 加载
// require(["module","../app"],function(module,app){})
// 3、CMD => SeaJS
define(function(require,exports,module){
var a = require('./a');
a.doSomething();
})
// 4、UMD =>CommonJS和AMD的糅合
(function (window,factory){
// 判断是否node环境
if(typeof module === 'object' && typeof module.exports === 'object') {
module.exports = factory();
}
// 判断是否AMD规范
else if(typeof define === 'function' && define.amd) {
define(factory)
}
// 使用浏览器环境
else {
window.eventUtil = factory()
}
})(this, function() {
// module
})
ES6模块化规范
Ⅰ. 默认导出
// 导出:constants.ts
export default {
number: 1008611
}
// 导入
// import constants from './constants'
Ⅱ. 分别导出
export const a = 1;
export function add<T extends number>(a: T, b: T) {
return a + b
}
// 导入
// import { a as a_rename,add } from './2'
// import * as util from './2'
Ⅲ. 动态引入
通过import方法动态引入,.then接收
if(true) {
import('./test').then(res => {
console.log(res)
})
}