TypeScript学习笔记:对象类型

2019-01-2510:30:28WEB前端开发Comments2,710 views字数 3529阅读模式

TypeScript中,利用接口(Interfaces)来定义对象的类型。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html

在面向对象语言中,接口(Interfaces)、它是对行为的抽象,而具体如何行动需要由类(classes)去实现(implements)。 在TypeScript中没有接口的概念,在编译成JavaScript的时候,所有的接口会被擦出掉,而TypeScript的核心之一就是类型检查。 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约并让代码看起来更好理解。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html

TypeScript中的接口

可用于对对象的形状进行描述,也可用于对类的一部分进行抽象,如:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html

interface Person {
    name:string;
    age:number;
}

function put(person:Person){
    console.log("hello" + person.name+"I'm"+ person.age);
}

let Tom: Person = { //这里的对象只要包含必要的属性且值类型正确就可以
    name: 'Tom',
    age: 25
};
复制代码

如果不给传进去的对象指定是接口类型的数据,那么传入的对象参数可以包含其他属性,编译器会检查必要的属性是否存在且判断类型是否正确。 如果是是指定了接口类型的数据,多属性和少属性均会出错文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html

let Tom: Person = {//两种情况均不允许
    name: 'Tom'
};

let Tom: Person = {
    name: 'Tom',
    age: 25,
    gender: 'male'
};
复制代码

可选属性

在实际的开发中,接口里的属性不全是需要的,就可以使用可选属性:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html

带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个?符号。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html

//这里name和age均是可选属性,在传对象的时候name和age可有可无
interface Person {
    name?: string;
    age?: number;
}
function getInfo(p:person){
    console.log(p.name);
    console.log(p.age);
}

let Tom ={name:'tom'}
let Tom ={age:20}
getInfo(Tom);

复制代码

任意属性

如果我们希望一个借口有任意的属性,可使用 [propName: string]: any来实现:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html

interface Person {
    name: string;
    age?: number;
    [propName: string]: any;
}

let Tom: Person = {
    name: 'Tom',
    gender: 'male'
};
复制代码

一旦定义了任意属性,则确定和可选属性必须是他的子属性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html

let tom: Person = {
    name: 'Tom',
    age: 25,
    gender: 'male'
};
//error TS2411: Property 'age' of type 'number' is not assignable to string index type 'string'.
复制代码

这里的任意属性是string,而age是number,number不是string的子属性,所以报错文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html

只读属性

如果我们希望对象的属性只能在对象创建时候修改其值,在属性名的前面用readonly来指定只读属性:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html

interface Person {
    readonly id: number;
    name: string;
    age?: number;
    [propName: string]: any;
}

let tom: Person = {
    id: 89757,
    name: 'Tom',
    gender: 'male'
};

tom.id = 9527;
//error TS2540: Cannot assign to 'id' because it is a constant or a read-only property.
复制代码

定义只读数组

TypeScript具有ReadonlyArray类型,它与Array相似,只是把所有可变方法去掉了,因此可以确保数组创建后再也不能被修改:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html

let a: ReadonlyArray<number> =[1,2,3,4];
a[0] =2;//error
a.length = 9;//error
复制代码

函数类型

为了使用接口表示函数类型,我们需要给接口定义一个调用签名。 它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html

interface getStr{
/* 函数传入两个number类型的参数,返回一个string*/
    (x:number,y:number):string;
}
let myStr: getStr;
myStr = function(grade:number,class:nember){
    return `${grade}年级${class}班`;
}
console.log(myStr(2,3)); //2年级3班
复制代码

可索引类型

与使用接口描述函数类型差不多,我们也可以描述那些能够“通过索引得到”的类型,比如a[10]或ageMap["daniel"]。 可索引类型具有一个 索引签名,它描述了对象索引的类型,还有相应的索引返回值类型文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html

interface StringArray {
  [index: number]: string;
}

let myArray: StringArray;
myArray = ["Bob", "Fred"];

let myStr: string = myArray[0];//打印Bob
复制代码

定义了StringArray接口,它具有索引签名。 这个索引签名表示了当用 number去索引StringArray时会得到string类型的返回值文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html

TypeScript支持两种索引签名:字符串和数字。 可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型。 这是因为当使用 number来索引时,JavaScript会将它转换成string然后再去索引对象。 也就是说用 100(一个number)去索引等同于使用"100"(一个string)去索引,因此两者需要保持一致。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html

类类型

一个类去实现接口,而不是直接把接口拿来用文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html

interface Clock{
//定义一个由属性和方法的接口
    currentTime:Date;
    setTime(d:Date);
}
//Time类实现了Clock接口
class Time implements Clock{
    currentTime:Date;
    setTime(d:Date){
        this.currentTime = d
    }
    constructor(h: number, m: number) { }//类的静态部分,不会检查
}
复制代码

继承接口

和类一样,接口也可以相互继承。 这让我们能够从一个接口里复制成员到另一个接口里,可以更灵活地将接口分割到可重用的模块里。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html

//接口可以继承接口  并且可以多继承
interface shape{
    color:string;
}
interface pen extends shape{
    width:number;
}//创建一个对象并指定泛型
circle.color="red";//这里可以获取color属性
circle.width=2;//有width属性
复制代码

一个接口继承多个接口,创建多个接口的合成接口文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html

interface Shape {
    color: string;
}

interface PenStroke {
    penWidth: number;
}

interface pen extends Shape, PenStroke {
    sideLength: number;
}

let square = <pen>{}; //创建一个对象并指定泛型
square.color = "blue";
square.sideLength = 10;
复制代码

混合类型

所谓的混合类型就是在一个接口中定义多种类型,比如属性,函数,数组等:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html

interface Counter {
    (start: number): string;
    interval: number;
    reset(): void; //没有返回值的函数
}

function getCounter(): Counter {
    let counter = <Counter>function (start: number) { };
    counter.interval = 123;
    counter.reset = function () { };
    return counter;
}

let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;

作者:banggan
链接:https://juejin.im/post/5c45511af265da617265c489
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html

文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/9378.html
  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/gcs/9378.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定