陕西网站建设公司找哪家好,东莞优化公司首选3火星,wordpress绕过媒体,传播公司可以做门户网站吗TypeScript 的类型兼容性是基于结构子类型的。 结构类型是一种只使用其成员来描述类型的方式。 interface Named {name: string;
}class Person {name: string;
}let p: Named;
p new Person();// 赋值成功#xff0c;因为都是结构类型#xff0c;只要Person 类型的包含 Nam… TypeScript 的类型兼容性是基于结构子类型的。 结构类型是一种只使用其成员来描述类型的方式。 interface Named {name: string;
}class Person {name: string;
}let p: Named;
p new Person();// 赋值成功因为都是结构类型只要Person 类型的包含 Named 的属性关于可靠性的注意事项
TypeScript 的类型系统允许某些在编译阶段无法确认其安全性的操作。 例如上面的Named 接口 和 Person 类应该属于不同的类型但是在 TypeScript 上只要属性包含就是兼容的。
探究
interface Named {name: string;
}let x: Named;let y {name: Alice, location: Seattle};
x y; // 可以赋值// 这里检车 y 是否能赋值给x编译器检查x中的每个属性看看是否能再y中找到所有对应的属性。找到了就是可以兼容缺少属性就不能兼容console.log(x);function greet(n: Named) {console.log(n.name);
}greet(y);
// 检查属性也适用类型兼容性规则比较两个函数
let x (a: number) 0;
let y (b: number, s: number) 0;// y x; // ok
// x y; // Error
/*** 要查看x是否能赋值给y首先看它们的参数列表。 x的每个参数必须能在y里找到对应类型的参数。 注意的是参数的名字相同与否无所谓只看它们的类 * 型。 这里x的每个参数在y中都能找到对应的参数所以允许赋值。* 第二个赋值错误因为y有个必需的第二个参数但是x并没有所以不允许赋值。*/为什么 x 可以赋值给 y。就像 Array.forEach 一样
let items [1, 2, 3];/** 完整参数列表 */
items.forEach((item, index, array) {console.log(item);
});/**一个参数 */
items.forEach(item console.log(item));比较函数之间的返回值类型
let x () ({name: Alice});
let y () ({name: Alice, location: Seattle});x y; // Ok
// y x; // Error类型系统强制源函数的返回值类型必须是目标函数返回值类型的子类型。
函数参数双向协变 当比较函数参数类型时只有当源函数参数能够赋值给目标函数或者反过来时才能赋值成功。 enum EventType {Mouse,Keyboard,
}interface Event {timestamp: number;
}interface MouseEvent extends Event {x: number;y: number;
}interface KeyEvent extends Event {keyCode: number;
}function listenEvent(eventType: EventType, handler: (n: Event) void) {/* ... */
}// 不可靠 但有用
listenEvent(EventType.Mouse, (e: MouseEvent) console.log(e.x , e.y));// 替代方案 - 类型断言 - 明确类型
listenEvent(EventType.Mouse, (e: Event) console.log((MouseEvente).x , (MouseEvente).y),
);
listenEvent(EventType.Mouse, (e: Event) void(((e: MouseEvent) console.log(e.x , e.y))
));// 报错不兼容
// listenEvent(EventType.Mouse, (e: number) console.log(e));可选参数和剩余参数 比较函数兼容性的时候可选参数与必须参数是可互换的。 源类型上有额外的可选参数不是错误目标类型的可选参数在源类型里没有对应的参数也不是错误。 function invokeLater(args: any[], callback: (...args: any[]) void) {/* ... Invoke callback with args ... */
}// 正确 - x, y 获取
invokeLater([1, 2], (x, y) console.log(x , y));// 疑惑
invokeLater([1, 2], (x?, y?) console.log(x , y));枚举 枚举类型与数字类型兼容并且数字类型与枚举类型兼容不同枚举类型之间是不兼容的。 enum Status {Ready,Waiting,
}
enum Color {Red,Blue,Green,
}let s: number Status.Ready;
s Color.Green; // Error类 类与对象字面量和接口差不多但有一点不同类有静态部分和实例部分的类型。 比较两个类类型的对象时只有实例的成员会被比较。 静态成员和构造函数不在比较的范围内. 类的私有成员和受保护成员会影响兼容性。 当检查类实例的兼容时如果目标类型包含一个私有成员那么源类型必须包含来自同一个类的这个私有成员。 同样地这条规则也适用于包含受保护成员实例的类型检查。 这允许子类赋值给父类但是不能赋值给其它有同样类型的类。 class Animal {feet: number;constructor(name: string, numFeet: number) {}
}class Size {feet: number;constructor(numFeet: number) {}
}let a: Animal;
let s: Size;a s; // OK
s a; // OK泛型
interface EmptyT {}
let x: Emptynumber;
let y: Emptystring;x y; // OK, because y matches structure of xx 和 y 是兼容的因为它们的结构使用类型参数时并没有什么不同。
interface NotEmptyT {data: T;
}
let x: NotEmptynumber;
let y: NotEmptystring;x y; // Error, because x and y are not compatible