ts筆記-型別相容性
阿新 • • 發佈:2021-11-02
型別相容性用於確定一個型別是否能賦值給其他型別。
any
任何型別都能被賦值給any
let foo: any = 123;
foo = 'hello';
結構化
TypeScript 物件是一種結構型別,因此只要結構匹配就是相容的
interface Point1 { x: number; y: number; } class Point2D { constructor(public x: number, public y: number) {} } // OK Point2D: {x: 1, y: 2} let p1: Point1 = new Point2D(1,2)
結構化資料如果包含原資料,也是可行的
interface Point2D { x: number; y: number; } interface Point3D { x: number; y: number; z: number; } const point2D: Point2D = { x: 0, y: 10 }; const point3D: Point3D = { x: 0, y: 10, z: 20 }; function PointFn(point: Point2D) { /* do something */ } // 額外的資訊,沒關係 PointFn(point3D) // 缺少資訊,不行 PointFn({x: 1})
函式
返回型別如果包含更多的資料,函式是相容的
interface Point2D {
x: number;
y: number;
}
interface Point3D {
x: number;
y: number;
z: number;
}
let f1 = (): Point2D => ({x: 1, y: 2})
let f2 = (): Point3D => ({x: 1, y: 2, z: 3})
// OK, f2包含更多的資料
f1 = f2
// ERROR
f2 = f1
函式的引數如果少於定義的型別,函式引數是相容的
// f1接受一個callback函式,callback函式接收兩個引數,無返回值
const f1 = (x: (err: any, data: any) => void) => {}
// OK
f1((err) => null)
// OK
f1(() => null)
// ERROR
f1((err, data, more) => null)
可選引數、確定引數和rest引數互相相容
let f1 = (x: number, y: number) => {}
let f2 = (...args: number[]) => {}
let f3 = (x?: number, y?: number) => {}
f1 = f2 = f3
f3 = f2 = f1
f1 = f3 = f2
列舉
列舉與數字型別相互相容
enum Status {
Ready,
Waiting
}
let status = Status.Ready;
let num = 0;
status = num;
num = status;
不同列舉的列舉變數是不相容的
enum Status {
Ready,
Waiting
}
enum Color {
Red,
Blue,
Green
}
let status = Status.Ready;
let color = Color.Red;
status = color; // Error
類
建構函式和靜態成員不會被檢查
class Animal {
feet: number;
constructor(name: string, numFeet: number) {}
}
class Size {
feet: number;
constructor(meters: number) {}
}
let a: Animal = new Animal('wmui', 18);
let s: Size = new Size(18);
a = s; // OK
s = a; // OK
私有的和受保護的成員必須來自於相同的類
class Animal {
protected feet: number;
}
class Cat extends Animal {}
let animal: Animal;
let cat: Cat;
// 來之相同的類
animal = cat; // ok
cat = animal; // ok
class Size {
protected feet: number;
}
let size: Size;
// 來自不同的類
animal = size; // ERROR
size = animal; // ERROR
泛型
當型別引數被內部成員使用時,會影響相容性
interface Empty<T> {
data: T;
}
let x: Empty<number>;
let y: Empty<string>;
x = y; // Error
當型別引數沒有被內部使用時,不存在相容性問題
interface Empty<T> {}
let x: Empty<number>;
let y: Empty<string>;
x = y; // ok
如果尚未例項化泛型引數,則在檢查相容性之前將其替換為 any
父類相容子類,子類不相容父類
class List<T> {
add(val: T) {}
}
class Animal {
name: string;
}
class Cat extends Animal {
meow() {
// ..
}
}
// 父類相容子類
const animals = new List<Animal>();
animals.add(new Animal()); // ok
animals.add(new Cat()); // ok
// 子類不相容父類
const cats = new List<Cat>();
cats.add(new Animal()); // Error
cats.add(new Cat()); // ok
常用網站:
SegmentFault |
GitHub |
掘金社群