類型檢查
類型兼容性
x、y屬性一樣,多的那個(gè)類型可以被賦值給少的那個(gè)
interface x {
a: number;
b: number;
}
interface y {
a: number;
b: number;
c: number;
}
let aobj: x = { a: 1, b: 2 };
let bobj: y = { a: 1, b: 2, c: 3 };
aobj = { a: 1, b: 2, c: 3 };// 不可以
aobj = bobj; // 可以
bobj = aobj;// 不可以
函數(shù)兼容性
type Handler = (a:number,b:number) => void;
function task(params: Handler) {
return params;
}
入?yún)榛A(chǔ)數(shù)據(jù)類型
-
入?yún)?/strong>多的可以兼容入?yún)⑸俚?/li>
- 返回值是對(duì)象,屬性少的可以兼容屬性多的
- 可選參數(shù)與剩余參數(shù):
type Handler1 = (a: number, b: number) => void;// 固定參數(shù)
type Handler2 = (a?: number, b?: number) => void;// 可選參數(shù)
type Handler3 = (...rest: number[]) => void;// 剩余參數(shù)
let h1: Handler1 = (a: number, b: number) => { };
let h2: Handler2 = (a?: number, b?: number) => { };
let h3: Handler3 = (...rest: number[]) => { };
h1 = h2 = h3;
- 剩余參數(shù)視為無限多參數(shù),由于第1條成立,所以剩余參數(shù)可以兼容固定參數(shù)和可選參數(shù)
修改
"strictFunctionTypes": false,
- 剩余參數(shù)可以兼容固定參數(shù)和可選參數(shù)
- 可選參數(shù)可以兼容固定參數(shù)和可選參數(shù)
入?yún)閷?duì)象
- 對(duì)象屬性多的可以兼容對(duì)象屬性少的;可以理解為入?yún)⒍嗟目梢约嫒萑雲(yún)⑸俚摹?/li>
interface Point2D{
x: number;
y: number;
}
interface Point3D{
x: number;
y: number;
z: number;
}
let p2d=(point: Point2D) => { };
let p3d = (point: Point3D) => { };
p2d = p3d;// 不可以 修改"strictFunctionTypes": false, 可以
p3d = p2d;// 可以
返回值類型
- 返回為對(duì)象,則屬性少的兼容屬性多的
枚舉兼容性
enum Fruit {
Apple = 2,
Banana = 3
}
let a: number = Fruit.Apple;// 可以
Fruit.Apple = Fruit.Banana;// 不可以
類兼容
class A {
state: number;
constructor(val: number) {
this.state = val;
}
run(): number {
return this.state;
}
}
class B {
state: number;
static id: number;
constructor(val: string) {
}
run(): number {
return this.state;
}
walk(): number {
return;
}
}
let a = new A(1);
let b = new B('b');
a = b;// 可以
b = a;// 不可以
- 靜態(tài)成員和構(gòu)造函數(shù)不參與比較
- 類的私有成員和受保護(hù)成員,只允許子類賦值給父類
泛型兼容
interface A<T>{
data: T;
}
let x: A<number>;
let y: A<string>;
x = y; // T被使用時(shí)不可以,不被使用時(shí)可以
- 沒有指定類型兼容時(shí),T視為any
高級(jí)類型
交叉類型
interface A {
run(): void;
}
interface B {
walk(): void;
}
let c: A & B = {
run() { },
walk() { }
}
聯(lián)合類型
let x: string | number;
let y: 'a' | 'b' | 'c';
let z = 1 | 2 | 3 | 4;
interface Square {
kind: "square";
size: number;
}
interface Rectangle {
kind: 'rectangle';
width: number;
height: number;
}
type Shape = Square | Rectangle;
function area(s: Shape) {
switch (s.kind) {
case "square":
return s.size * s.size;
case "rectangle":
return s.height * s.width;
default:
return ((e: never) => { throw new Error(e) })(s)
// 約束在type而不給case處理的情況,即強(qiáng)制要求每一個(gè)type都必須處理
}
}
索引類型
// keyof T
interface Obj {
a: number,
b: string
}
let key: keyof Obj;
// T[K]
let value: Obj['a']
// T extends U
function getValue<T, K extends keyof T>(obj: T, keys: K[]): T[K][] {
return keys.map(key => obj[key]);
}
映射類型
interface Obj {
a: string;
b: string;
c: number;
}
// 同態(tài)
// 把所有類型變成只讀的
type ReadonlyObj = Readonly<Obj>;
// 把所有類型變成可選的
type PartialObj = Partial<Obj>;
// 限定選取范圍
type PickObj = Pick<Obj, 'a' | 'b'>;
// 非同態(tài):會(huì)創(chuàng)建新的屬性
// x,y屬性都是Obj類型
type RecordObj = Record<'x' | 'y', Obj>;
let obj: RecordObj = {
x: {
a: 'a',
b: 'b',
c: 1
},
y: {
a: 'a',
b: 'b',
c: 1
}
}
namespace
- 使用export將function導(dǎo)出
namespace Square{
let a = 1;
let b = 2;
export function task() {
return a + b;
}
}
Square.task();

編譯
合并
- 兩個(gè)文件有同名的命名空間,則命名空間會(huì)發(fā)生合并,但不能有同名export的東西;
- 與函數(shù)合并
命名空間聲明需要放在后面。
function Lib() { }
namespace Lib {
export let version = '1.0';
}
console.log(Lib.version);// 1.0
- 與類合并
命名空間聲明需要放在后面。
class C { }
namespace C {
export let state = 1;
}
console.log(C.state);// 1
state為class C的靜態(tài)成員
- 與enum合并
命名空間聲明可以不放在后面。
enum Color {
Red,
Yellow,
Bule
}
namespace Color {
export function mix() { }
}
console.log(Color);
