这是我参与「第四届青训营 」笔记创作活动的第12天
高级类型
联合/交叉类型
联合类型:IA|IB;联合类型表示一个值可以是几种类型之一
交叉类型: IA & IB;多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性
const bookList = [{ author: 'xiaoming',
type: 'history',
range: '2001-2021}
,{
author: 'xiaoli',
type: 'story'
theme: 'love',
}]
type IBookList = Array<{
author: string;
})&{
type: 'history';
range: string;
}|{
type: 'story';
theme: string;
}>
类型保护与类型守卫
interface IA {a: 1, al: 2}
interface IB {b: 1, b1: 2 }
function log(arg: IA | IB){
/*报错:类型"IA|IB"上不存在属性"a"。类型"IB"上不存在属性"a"。*/
//在类型保护中
/*结论:访问联合类型时,处于程序安全,仅能访问联合类型中的交集部分*/
if (arg.a) {
console. log(arg.a1)
}
else{
console. log(arg.b1);
}
}
类型改造
类型守卫只有当两个类型完全没有重合点的时候 需要写一个类型守卫
interface IA {a: 1, al: 2}
interface IB {b: 1, b1: 2}
//声明一个类型守卫
/*类型守卫:定义一个函数,它的返回值是一个类型谓词,生效范围为子作用域*/
function getIsIA(arg: IA | IB): arg is IA {
//as的类型断言
//当他存在a的时候,断言她一定是个IA类型
return !!(arg as IA).a;
}
function log2(arg: IA | IB){
if (getIsIA(arg)) {
console. log(arg.a1)
}else{
console. log(arg.b1);
}
}
//实现函数reverse
//其可将数组或字符串进行反转
function reverse(target: string | Array<any>){
/* typof类型保护
if (typeof target === 'string') {
return target.split(''). reverse().join('')
}
* instance类型保护*/
//进行数组判别
if (target instanceof Object) {
return target. reverse();
}
}
//实现函数logBook类型
//函数接受书本类型,并logger出相关特征
function logBook(book: IBookItem) {
//联合类型+类型保护=自动类型推断
if (book. type === 'history')
{
console. log (book. range)
} else{
console. log (book. theme);
}
}
高级类型
sourobj和targetobj做合并
//实现merge函数类型
//要求sourceObj必须为targetObj的子集
function mergel(sourceObj, targetobj) {
const result = {...source0bj };
for(let key in targetobj) {
const itemVal = sourceObj [key];
itemVal && ( result [key] = itemVal );
}
return result;
}
function merge2(source0bj, targetobj) {
return {...source0bj, ...target0bj}
}
不知道传入的人不知道传入的是什么object
interface ISourceObj{
x?: string;
y?: string;
}
interface ITargetobj {
x: string;
y:string
}
type IMerge = (sourceObj: ISourceobj, target0bj: ITarget0bj)
=>ITargetobj;
/**
*类型实现繁琐:若obj类型较为复杂,则声明source和target便需要大量重复2遍
*容易出错:若target增加/减少key,则需要source联动去除
//xy或者any都没办法严格限定
*/
通过使用泛型 定义的时候不明确 使用的时候明确
interface IMerge {
//Record<string, any>> 简单的any的表达
<T extends Record<string, any>>(sourceObj: Partial<T>, target0bj: T) : T;
}
type IPartial<T extends Record<string, any>> = {
[P in keyof T]?: T[P];
}
//索引类型:关键字【keyof】 ,其相当于取值对象中的所有key组成的字符串字面量,如
type IKeys = keyof{ a: string; b: number} ); // => type IKeys = "a" | "b"//关键字【in】,其相当于取值 字符串字面量中的一种可能,配合泛型P,即表示每个key
//关键字【?】 ,通过设定对象可选选项,即可自动推导出子集类型
高级类型通过基础语法表达,partical是内置类型,直接使用就可以
函数返回值类型
//实现函数delayCall的类型声明
//delayCall接受一个函数作为入参,其实现延迟1s运行函数
//其返回promise,结果为入参函数的返回结果
function delayCall(func) {
return new Promise (resolve => {
setTimeout(() =>{
const result = func();
resolve(result);
}, 1000);
});
}
//类型声明 :入参 出参
//通过泛型
//泛型限定,定义了一个函数 返回范围最大的函数
type IDelayCall = <T extends () => any>(func: T) => ReturnType<T>;
//定义时不明确 使用泛型
//function设置了更大的限定 出入参都可以是最大范围 符合函数标准就行
//?:三元表达式
//extends这里是个声明 类型推断 语法类似三元表达式 类型匹配 作用等于三等号
type IReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R: any
//关键字【extends】跟随泛型出现时,表示类型推断,其表达可类比三元表达式
//如T-判断类型?类型A:类型B
//关键字【infer】出现在类型推荐中,表示定义类型变量,可以用于指代类型
//如该场景下,将函数的返回值类型作为变量,使用新泛型R表示,使用在类型推荐命中的结果中
工程应用
浏览器WEB
TypescriptI程应用 - Web
1、 配置webapack loader相关配置
webpack不能识别的文件转化为可以识别的文件,ts转js
2、 配置tsconfig.js文件
这个文件官网有配置项
3、运行webpack启动/打包
4、 loader处理ts文件时,会进行编译与类型检查
NODEJS
01.使用TSC编译
- 安装Node5npm
- 配置tsconfig.js文件
- 使用npm安装tsc
- 使用tsc运行编译得到js文件