typescript(2)|青训营笔记

58 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天

ts高级类型

联合|类型 交叉&类型

引入

const bookList = [{
	author:'xiaoming',
    type:'history',
    range:'2001-2021',
},{
    author:'xiaoli',
    type:'story',
    theme:'love',
}]
//为书籍列表编写类型
//类型繁杂,存在较多重复
interface IBookList = Array<{
    author: string;
    type: string;
    range: string;
}
interface IStoryBook {
    author: string;
    type: string;
    theme: string;
}
type IBookList = Array<IHistoryBook | IStoryBook>;

更好地写法

·联合类型: IA│IB;联合类型表示一个值可以是几种类型之一 ·交叉类型: IA&IB;多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性

type IBookList = Array<{author: string;} & ({type: 'history'; range: string;} | {type: 'story';theme: string;})
//或者这样写
type IBookList = Array<{
	author: string;
} & ({
    type: 'history';
    range: string;
} | {
    type: 'story';
    theme: string;
})>                     
                       

类型保护和类型守卫

js中没问题 但 ts中有问题

报错:类型“IA|IB"上不存在属性"a”。类型“IB"上不存在属性“a"。

结论:访问联合类型时,处于程序安全,仅能访问联合类型中的交集部分

interface IA { a: number, a1: number}
interface IB { b: number, b1: number}

function log(arg: IA | IB){
    if(arg.a){
        console.log(arg.a1);
    }else{
        console.log(arg.b1);
    }
}

修改版本

类型守卫 定义一个函数,他的返回值是一个类型谓词,生效范围为子作用域

修改版本 使用类型谓词 is

TypeScript 中的 is 关键字,它被称为类型谓词,用来判断一个变量属于某个接口或类型

is 关键字一般用于函数返回值类型中,判断参数是否属于某一类型,并根据结果返回对应的布尔类型。

//类型守卫 定义一个函数,他的返回值是一个类型谓词,生效范围为子作用域
funciton getIsIA(arg: IA|IB): arg is IA{
    return !!(arg as IA).a;
}
function log2(arg:IA | IB){
    if(getIsIA(arg)){
        console.log(arg.a1);
    }else{
        console.log(arg.b1);
    }
}

type instanceof 类型保护

当两种类型没有重合点的时候才要写类型守卫

  • reverse只能对数组进行翻转
  • 但是同时要对字符串和数组进行翻转就需要使用类型保护

split 是将一个按照指定分隔符,分隔放入数组

join 是将一个数组有指定分隔符分隔放入数组 join('分隔符')

function reverse(target: string| Array<any>){
	if(typeof target === 'string'){
        return target.split('').reverse().join('');
    }
    if(target instanceof Object){
        return target.reverse();
    }
}

联合类型+类型保护 = 自动类型推断

type IBookList = Array<{
	author: string;
} & ({
    type: 'history';
    range: string;
} | {
    type: 'story';
    theme: string;
})>                     

//函数接受书本类型 并logger出相关特征
function logBook(book: IBookItem){
    if(book.type === 'history'){
        console.log(book.range);
    }else{
        console.log(book.theme);
    }
}

Record<Key,val>

Record<K,T>构造具有给定类型T的一组属性K的类型。在将一个类型的属性映射到另一个类型的属性时,Record非常方便。

他会将一个类型的所有属性值都映射到另一个类型上并创造一个新的类型.

示例:

interface EmployeeType {
    id: number
    fullname: string
    role: string
}
 
let employees: Record<number, EmployeeType> = {
    0: { id: 1, fullname: "John Doe", role: "Designer" },
    1: { id: 2, fullname: "Ibrahima Fall", role: "Developer" },
    2: { id: 3, fullname: "Sara Duckson", role: "Developer" },
}
 
// 0: { id: 1, fullname: "John Doe", role: "Designer" },
// 1: { id: 2, fullname: "Ibrahima Fall", role: "Developer" },
// 2: { id: 3, fullname: "Sara Duckson", role: "Developer" }

Record的工作方式相对简单。在这里,它期望数字作为类型,属性值的类型是EmployeeType,因此具有idfullNamerole字段的对象。

keyof & in & ?

keyof 相当于取值对象中所有的key组成的字符串字面量

type IKey = keyof {a: string; B: number}; // => type IKeys = "a" | "b"

in 其去之相当于 字符串字面量 中的一种可能,配合泛型P 即表示每个key

? 设定可选对象,自动导出自己类型

infer

ts的使用

webpack打包 ts -> js

TSC编译

  1. 安装 npm 与 node

  2. 使用 npm 安装tsc

  3. 配置tsconfig.js

  4. 使用tsc运行编译的到js 文件

自我提问

高级数据类型有哪些?

类型 保护和类型守卫有哪些

参考网站

第十六节: TypeScript类型谓词( is关键字 ) - 简书 (jianshu.com)