- 结构兼容则类型兼容
interface Person {
firstName: string;
lastName: string;
}
function greeter(person: Person) {
return "Hello," + person.firstName + " " + person.lastName;
}
var user = { firstName: "Jane", lastName: "User" };
document.body.innerHTML = greeter(user);
- 在构造函数参数中使用public是一种简写形式,它将自动创建具有该名称的属性
class Student {
fullName: string;
constructor(public firstName, public middleInitial, public lastName) {
this.fullName = firstName + " " + middleInitial + " " + lastName;
}
}
interface Person {
firstName: string;
lastName: string;
}
function greeter(person : Person) {
return "Hello, " + person.firstName + " " + person.lastName;
}
var user = new Student("Jane", "M.", "User");
document.body.innerHTML = greeter(user);
- 添加类型断言
interface Options { color: string; volume: number }
let options = {} as Options;
options.color = "red";
options.volume = 11;
- 解构
// 这可是真真正正的对象哦哦哦
let o = {
a: "foo",
b: 12,
c: "bar"
}
let { a, b } = o;
type C = { a: string, b?: number }
function f({ a, b }: C): void {
// ...
}
function f({ a, b = 0 } = { a: "" }): void {
// ...
}
f({ a: "yes" }) // ok, default b = 0
f() // ok, default to {a: ""}, which then defaults b = 0
f({})
- 展开
let defaults = { food: "spicy", price: "$$", ambiance: "noisy" };
let search = { food: "rich", ...defaults };
//对象展开还有其它一些意想不到的限制。 首先,它只包含自身的可枚举的属性。 首先,当你展开一个对象实例时,你会丢失其方法
class C {
p = 12;
m() {
}
}
let c = new C();
let clone = { ...c };
clone.p; // ok
clone.m(); // error!
- 接口
如果一个对象字面量存在任何“目标类型”不包含的属性时,你会得到一个错误
interface SquareConfig {
color?: string;
width?: number;
}
// error: 'colour' not expected in type 'SquareConfig'
let mySquare = createSquare({ colour: "red", width: 100 });
绕开这些检查非常简单。 最简便的方法是使用类型断言
let mySquare = createSquare({ width: 100, opacity: 0.5 } as SquareConfig);
或者使用字符串索引签名
前提是你能够确定这个对象可能具有某些做为特殊用途使用的额外属性。 如果 SquareConfig带有上面定义的类型的color和width属性,并且还会带有任意数量的其它属性,那么我们可以这样定义它:
interface SquareConfig {
color?: string;
width?: number;
[propName: string]: any;
}
还有最后一种跳过这些检查的方式,这可能会让你感到惊讶,它就是将这个对象赋值给一个另一个变量: 因为 squareOptions不会经过额外属性检查,所以编译器不会报错。
let squareOptions = { colour: "red", width: 100 };
let mySquare = createSquare(squareOptions);
接口描述函数类型
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
let result = source.search(subString);
if (result == -1) {
return false;
}
else {
return true;
}
}
如果单单只定义了一个匿名函数。则可以理解我构造函数,如果定义多个函数的话,上述方式就报错
交叉类型
将多个类型叠加到一起变为一种类型,但是该类型包含了所需类型的所有类型的特性
function extedn<T,U> (first:T,second:U):U & T{
...
}
class Person{
}
class Loggable {
log():void
}
var jim = extend(new Person(),new Loggable());
...
联合类型 (U | T)
联合类型表示一个值可以是几种类型之一,但是该值只能访问次此联合类型的所有共有的成员
类型保护和区分类型
在使用联合类型的时候,我们不能确定我们拿到的值中是否有需要的类型,这时候该怎么判断??
let pet = getSmallPet();
if((<Fish>pet).swim){
(<Fish>pet).swim();
}else{
(<Bird>pet).fly();
- 使用谓词
is
function isFish(pet:Fish|Bird) :pet is Fish{
return (<Fish>pet).swim !== undefined;
}
if(isFish(pet)){
...
}else{
...
}
2 . 使用 typeof
typeof 只能识别 === 或者 !==
typeName 必须是 string
, number
,boolean
,symbol
function isNumber(x:any): x is number{
return typeof x === "number";
}
if(isNumber(a)){
...
}
3 . instanceof