TS中的高级类型:
- 交叉类型
- 联合类型
- 类型保护
- null和undefined
- 类型别名
- 可辨识联合
一 交叉类型
交叉类型(&):用于组合多个类型为一个类型,常用于对象类型
interface Employee {
employeeID: number;
age: number;
}
interface Manager {
stockPlan: boolean;
}
type ManagementEmployee = Employee & Manager;
let newManager: ManagementEmployee = {
employeeID: 12345,
age: 34,
stockPlan: true
};
const mergeFunc = <T, U>(arg1: T, arg2: U): T & U => {
return Object.assign(arg1, arg2)
}
console.log(mergeFunc({a:'aaa'},{b:'bbb'}))
二 联合类型
联合类型使用|分隔每种类型
let multiType: number | boolean;
multiType = 20;
multiType = true;
multiType = "twenty";
三 类型保护
1.类型断言as
interface Bird {
fly: boolean;
sing: () => {};
}
interface Dog {
fly: boolean;
bark: () => {};
}
function trainAnmial(animal: Dog | Bird) {
if (animal.fly) {
(animal as Bird).sing();
} else {
(animal as Dog).bark();
}
}
2.typeof实现类型保护
function add(first: string | number, second: string | number) {
if (typeof first === 'string' || typeof second === 'string') {
return `${first}${second}`;
}
return first + second;
}
注意:如果使用typeof来实现类型保护, 那么只能保护number/string/boolean/symbol类型,不能用于null,同时也不能用于interface和type定义的类型,因为这些类型在运行时就不在了。 3.instanceof实现类型保护 instanceof用于校验类,类的类型信息会在运行时保留。
class A {
name:string = "1"
}
class C {
name1:string ="222"
}
function AM(param:A |C) {
if(param instanceof A){
}
if(param instanceof C){
}
}
4.in语法实现类型保护 in操作符对对象上的属性是否存在进行安全检查。
interface Dog {
name: string
bark: () => void
}
interface Bird {
name: string
fly: () => void
}
function doSomething(args: Dog | Bird) {
if ('bark' in args) {
args.bark()
} else {
args.fly()
}
}
5.=== 和 !== 使用===和!==判断字面量类型
type CheckState = 'yes' | 'no' | 'unknown'
function doSomething(args: CheckState) {
if (args === 'yes') {
console.log('check state is yes')
} else if (args === 'no') {
console.log('check state is no')
} else {
console.log('unknown check state')
}
}
四 null和undefined
null和undefined默认情况下是所有类型的子类型,即可以赋值给任意类型。但是如果在tsconfig.js中设置strictNullChecks为true时,就不能赋值给除它们自身以及void之外的类型了。想要使用可以配合联合类型来实现,如:
let s2: string | null = 'hi'
如果设置了"strictNullChecks": true,可选参数会被自动加上 |undefined,如果想要去除的话可以使用以下几种方法: 1.可选链(?.)
interface User {
name: string
address?: {
street: string
}
}
function printStreet(user: User) {
const streetInfo = user.address?.street
if (streetInfo === undefined) {
console.log('No street info')
} else {
console.log(streetInfo)
}
}
let user: User = {
name: 'O.O'
}
printStreet(user)
2.空值合并(??) 它允许编写在处理null或undefined时有回退的表达式。
function printName(name: string | null | undefined) {
console.log(`${name ?? '无名氏'}`)
}
printName(null)
printName('O.O')
3.空断言(!) 有时候忽略一个值为 null 或 undefined 的可能性是有意义的。一个简单的方法就是使用类型转换,但是 TypeScript 也提供了 ! 运算符作为方便的快捷方式。
function getValue(): string | undefined {
return 'hello'
}
let value = getValue()
value.length
value!.length
五 type类型别名
type stringType = string
let str:stringType = 'abc'
type PositionType<T> = {x:T, y:T}
const position1: PositionType<number> = {
x: 1,
y: 2
}
const position2: PositionType<string> = {
x: 'left',
y: 'top'
}
type Childs<T> = {
current: T,
child?: Childs<T>
}
const children:Childs<string> = {
current: 'first',
child: {
current: 'second',
child: {
current: 'third'
}
}
}
interface Square {
kind:'square',
size: number
}
interface Rectangle {
kind:'rectangle',
height:number,
width:number
}
interface Circle {
kind: 'circle',
radius: number
}
type Shape = Square | Rectangle | Circle
function assertNever(value: never):never {
throw new Error('unexpected error: ' + value)
}
function getArea(s: Shape):number{
switch(s.kind){
case 'square': return s.size * s.size;break;
case 'rectangle': return s.width * s.height;break;
case 'circle': return Math.PI * s.radius ** 2;break;
default: return assertNever(s)
}
}
|