typeScript学习(二)
联合类型和类型保护
联合类型 |
// 联合类型和类型保护
interface Bird {
fly: boolean
sing: () => {}
}
interface Dog {
fly: boolean
bark: () => {}
}
//联合类型
function trainAnial(animal: Bird | Dog) {
// 使用联合类型的话ts不知道你的animal是哪个interface,所以会报错
animal.sing()
}
//类型保护
//这个时候就要用到类型断言,比如下面的(类型断言as的方式进行类型保护)
function trainAnial(animal: Bird | Dog) {
if (animal.fly) {
;(animal as Bird).sing()
}
;(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,不能用class)
class NumberObj {
count: number = 0
}
function addSecond(first: object | NumberObj, second: object | NumberObj) {
if (first instanceof NumberObj && second instanceof NumberObj) {
return first.count + second.count
}
return 0
}
枚举类型(可正查反查)
//枚举(可正查反查)
enum Status {
OFFline,
online,
deleted,
}
console.log(Status)
console.log(Status[0]) //OFFline
console.log(Status.OFFline) //0
// {
// '0': 'OFFline',
// '1': 'online',
// '2': 'deleted',
// OFFline: 0,
// online: 1,
// deleted: 2
// }
enum Status1 {
OFFline = 1,
online,
deleted,
}
console.log(Status1)
// {
// '1': 'OFFline',
// '2': 'online',
// '3': 'deleted',
// OFFline: 1,
// online: 2,
// deleted: 3
// }
泛型 generic 泛指的类型
// 泛型 generic 泛指的类型
function join<T, P>(first: T, second: P): T {
return first
}
join<string, string>('1', '2')
function map<ABC>(params: Array<ABC>) {
return params
}
map<string>(['123'])
类中的泛型以及泛型类型
//类中的泛型
interface Item {
name: string
}
// T继承了Item,表示T里面一定要有Item的所有属性
class DataManager<T extends Item> {
constructor(private data: T[]) {}
getItem(index: number): string {
return this.data[index].name
}
}
const data = new DataManager([{ name: '11' }])
// 泛型约束(用extends 联合类型或interface)
class DataManager2<T extends number | string> {
constructor(private data: T[]) {}
getItem(index: number): T {
return this.data[index]
}
}
interface Test {
name: string
}
const data = new DataManager2<number>([])
console.log(data.getItem(0))
// 如何使用泛型作为一个具体的类型注解
function hello<T>(param: T) {
return param
}
const func: <T>(param: T) => T = hello
namespace 命名空间(类似与模块化,闭包,外部访问不到里面的变量,只有export部分变量才可以被外部访问到)
//namespace 形成闭包,只把Home暴露出去,其他三个方法访问不了
namespace Home {
class Header {
constructor() {
const elem = document.createElement('div');
elem.innerText = 'This is Header';
document.body.appendChild(elem);
}
}
class Content {
constructor() {
const elem = document.createElement('div');
elem.innerText = 'This is Content';
document.body.appendChild(elem);
}
}
class Footer {
constructor() {
const elem = document.createElement('div');
elem.innerText = 'This is Footer';
document.body.appendChild(elem);
}
}
//namespace export(只导出Page,可以通过 new Home.Page访问得到)
export class Page {
constructor() {
new Header();
new Content();
new Footer();
}
}
}
全局类型(自己定义一个.d.ts文件)



也可以写成下面这种interface的语法,实现函数重载

上面是对变量和函数进行类型定义,下面是对对象进行类型定义


模块代码的类型描述文件(es6模块化d.ts,最后记得export导出)


泛型中keyof语法的使用
interface Person {
name: string
age: number
gender: string
}
//帮助理解
// type NAME = 'name';
// key: 'name';
// Person['name'];
// type T = 'age'
// key: 'age'
// Person['age']
// type T = 'gender'
// key: 'gender'
// Person['gender']
// 用泛型结合keyof的方式解决key值不准确的问题
// 1、keyof是遍历循环Person的key
// 2、例如 T extends name => 恒等于 type T = name 所以 参数key:name
class Teacher {
constructor(private info: Person) {}
getInfo<T extends keyof Person>(key: T): Person[T] {
return this.info[key]
}
}
const teacher = new Teacher({
name: 'zhen',
age: 28,
gender: 'male',
})
const test = teacher.getInfo('age')
console.log(test)

浙公网安备 33010602011771号