1、unknown是所有类型的父类型,其余类型都能够赋值给 unknown
let a: undefined = undefined;let b: null = null;let x2: unknown;x2 = a; //正确x2 = b; //正确
2、never 是任何类型的子类型,能够赋给任何类型
let a: undefined = undefined;let b: null = null;function err(): never { // OK throw new Error('error');}a = err(); //正确b = err(); //正确
3、any能够赋值给任何类型,任何类型能够赋值给any,除了any不能赋值给never(然而never却能够赋值给any)
let a: undefined = undefined;let b: null = null;let err: never;let y: any = 4;a = y; //正确b = y; //正确y = a; //正确y = b; //正确err = y ; //报错 不能将类型“any”调配给类型“never”。ts(2322)
4、子类型能够赋值给父类型。然而父类型不能赋值给子类型,必须加断言
let v: void;let a: undefined = undefined;v = a; //正确 a = v; //谬误 不能将类型“void”调配给类型“undefined”。ts(2322)a = v as undefined; //正确
那么通常状况下,如果一个办法或组件的属性,定义什么类型,咱们传入什么类型就完事了,为什么还要整顿这张图呢?
因为咱们有时,并不能十分准确的定义一个类型,咱们只想把一个子类型传进入,这样它也能辨认。
比方vue中:
<xx-upload :before-load="handleBeforeLoad">//setup ts代码let handleBeforeLoad = ()=>{}
这样传入会报错,因为你会发现before-load传入的类型是个由命名空间定义的自定义类型。
要么你准确的传入匹配的类型
import type { UploaderBeforeRead } from "xx/lib/upload/types"let beforeRead:UploaderBeforeRead = (file:File | File[]):boolean=>{}
要么传入一个any,接管一个any参数,因为第三条中"any能够赋值给任何类型,任何类型能够赋值给any"就能够解决。
let beforeRead:any = (file:any):boolean=>{}