// 交叉类型 交叉类型用&来定义,交叉类型相当于合并T对象和U对象,返回的对象要既包含T的属性也包含U的属性
const mergeFunc = <T, U>(arg1: T, arg2: U): T & U => {
let res = {} as T & U
res = Object.assign(arg1, arg2)
return res
}
console.log(mergeFunc({ a: '1' }, { b: '2' })) //{a: '1',b: '2'}
//类型保护 类型保护的作用 确定使用联合类型时使用的具体是哪个类型
const valueList = ['abc', 123]
const getRandomValue = () => { //返回的是string和number的联合类型,并且无法确定函数返回的类型是string还是number
const number = Math.random() * 10
if (number > 5) { return valueList[0] }
else return valueList[1]
}
const res = getRandomValue()
//普通方法
if ((res as string).length) { // 由于无法确定返回的是联合类型中的哪一种所以在调用方法之前要使用类型断言
console.log((res as string).length)
} else {
console.log((res as number).toFixed())
}
//类型保护方法一 自定义类型保护返回值是一个类型谓词,谓词为 parameterName is Type这种形式, parameterName必须是来自于当前函数签名里的一个参数名。
function isString(value:number | string): value is string {
return typeof value === 'string'
}
if (isString(res)) {
res.length // 上面是string类型,else后只有number类型
} else {
res.toFixed
}
//类型保护方法二 typeof类型保护使用两个条件 1、只能使用===或!==来比较 2、只能比较string\number\boolean\symbol中的一种
if (typeof res === 'string') {
console.log(res.length)
} else {
console.log(res.toFixed)
}
//类型保护方法三 instanceof类型保护
class Class1 {
public age = 11
constructor() {}
}
class Class2 {
public name = 'abc'
constructor() {}
}
function getRandomItem() {
return Math.random() < 0.5 ? new Class1(): new Class2()
}
let result = getRandomItem()
if (result instanceof Class1) {
result.age
} else {
result.name
}
null和undefined
//null和undefined
//默认情况下定义的所有数据类型都是type | undefined | null的联合类型
let a: string = undefined // 所以可以设置值为undefined
let b: string = null
//类型断言
function getSplicedStr(num: number | null): string {
function getRes(prefix: string) {
return prefix + num!.toFixed().toString() // 使用后跟!来断言不为null
}
num = num || 0.1
return getRes('xiecong-')
}
类型别名
//类型别名 相当于给类型起了一个新的名字,可以用新的名字取定义变量,类型别名不会新建一个类型,它创建了一个新名字来引用那个类型
type TypeString = string
let strTest1: string = '111'
let strTest2: TypeString = '222'
type PositionType<T> = { x: T, y: T }
const position1: PositionType<number> = {
x: 1,
y: 2
}
/* 可辨识联合要具有3个要素
1、要具有普通的单例类型属性 --- 可辨识的特征
2、一个类型别名包含了类型的联合
3、此属性上的类型保护
*/
interface Square{
kind: 'square'
size: number
}
interface Rectangle {
kind: 'rectangle'
width: number
height: number
}
interface Circle {
kind: 'circle'
radius: number
}
type Shape = Square | Rectangle | Circle //将三个接口做联合类型并起一个别名Shape
function area(s: Shape) {
// 使用三个类型中共有的可辨识特征kind属性做判断
switch (s.kind) {
case "square": return s.size * s.size;
case "rectangle": return s.height * s.width;
case "circle": return Math.PI * s.radius ** 2;
}
}
this类型
// this类型
class Counters {
constructor(public count: number = 0) { }
public add(value: number) {
this.count += value
return this // 通过返回this的形式实现了链式调用
}
public substract(value: number) {
this.count -= value
return this
}
}
let counter1 = new Counters(10)
counter1.add(3).substract(2) // 通过返回this的形式实现了链式调用