zoukankan      html  css  js  c++  java
  • typescript接口(学习笔记非干货)

    typescript的核心原则之一就是对所具有的shape类型检查结构性子类型化
    One of the core principles of typescript is to check structural subtyping of shape types
    在typescript中,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约
    In typescript, the function of an interface is to name these types and define contracts
    for your code or third-party code.

    function printLable(labelledObj:{label:string}){
        console.log(labelledObj.label);
    }
    let myObj={size:10,label:"Size 10 Object"};
    printLable(myObj);
    

    我们分析代码可以知道,一个对象有label对象,它的值类型是string类型
    If we analyze the code, we can see that an object has a label object whose value type is string type.
    使用接口重写上面的例子
    Rewrite the above example using an interface

    interface LabelledValue{
        label:string;
    }
    function printLable(labelledObj:LabelledValue){
        console.log(labelledObj.label);
    }
    let myObj={Size:10,label:"Size 10 Object"};
    printLable(myObj);
    //类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以
    /*The type checker does not check the order of attributes, as long as the corresponding 
    attributes exist and the type is correct.*/
    

    可选属性。option bags 模式时很常用。接口里的属性不会都是必选的。有些只是在某些条件下存在,或者根本不存在
    Optional properties. Option bags mode is often used. Attributes in interfaces are not always required.
    Some exist only under certain conditions, or nonexistent at all.
    即给函数传入的参数对象中只有部分属性赋值了。
    That is to say, only part of the parameter object passed in by the function is assigned to its attributes.

    interface SquareConfig{
        color?:string;
        width?:number;
    }
    function createSquare(config:SquareConfig):{color:string;area:number}{
        let newSquare={color:"white",area:100};
        if(config.color){
            newSquare.color=config.color;
        }
        if(config.width){
            newSquare.area=config.width*config.width;
        }
        return newSquare;
    }
    let mySquare=createSquare({color:"black"});
    

    只读属性
    Read-only attribute

    interface Point{
        readonly x:number;
        readonly y:number;
    }
    

    通过赋值一个对象字面量来构造一个Point
    Constructing a Point by assigning an object literal

    let p1:Point={x:20,y:20};
    p1.x=5;//error
    

    typescript具有readonlyArray类型,它与Array相似,只是把所有可变方法去掉了
    Typeescript has the readonlyArray < T > type, which is similar to Array < T > except that all the variable methods are removed.
    因此可以确保数组创建后再也不能被修改
    So you can make sure that arrays can never be modified after they are created.

    let a:number[]=[1,2,3,4];
    let ro:ReadonlyArray<number>=a;
    ro[0]=12;//error
    ro.push(5);//error
    ro.length=100;//error
    a=ro;//error
    

    用类型断言重写
    Rewrite with type assertions

    a=ro as number[];
    

    readonly vs const
    最早判断该用readonly还是const的方法是要看把它作为变量使用还是作为一个属性
    The earliest way to determine whether to use readonly or const is to use it as a variable or as an attribute
    作为变量使用的话用const,若作为属性使用则用readonly
    Use const as a variable and read only as an attribute
    额外的属性检查
    Additional property checking

    interface SquareConfig{
        color?:string;
        width?:number;
    }
    function createSquare(config:SquareConfig):{color:string;area:number}{
    }
    

    对象字面量会被特殊对待而且会经过 额外属性检查,当将它们赋值给变量或作为参数传递的时候。
    Object literals are treated specially and are checked for additional attributes when they are assigned to variables or passed as parameters.
    如果一个对象字面量存在任何“目标类型”不包含的属性时,你会得到一个错误。
    If an object literal has any attributes that the "target type" does not contain, you get an error.

    let mySquare=createSquare({colour:"red",100});
    

    绕开这些检查非常简单。 最简便的方法是使用类型断言:
    It's very simple to bypass these checks. The easiest way is to use type assertions:

    let mySquare=createSquare({100,opacity:0.5}as SquareConfig);
    

    最佳的方式是能够添加一个字符串索引签名,前提是你能够确定这个对象可能具有某些做为特殊用途使用的额外属性
    The best way to do this is to be able to add a string indexed signature, provided you can determine that
    the object may have some additional properties for special purposes.

    interface SquareConfig{
        color?:string;
        width?:number;
        [proName:string]:any;//任意数量的属性
    }
    

    它就是将这个对象赋值给一个另一个变量: 因为squareOptions不会经过额外属性检查,所以编译器不会报错。
    It assigns this object to another variable: because squareOptions does not undergo additional property checks,
    the compiler does not report errors.

    let squareOptions = { colour: "red",  100 };
    let mySquare = createSquare(squareOptions);
    

    函数类型
    Function Type
    接口能够描述JavaScript中对象拥有的各种各样的外形。
    除了描述带有属性的普通对象外,接口也可以描述函数类型。
    Interfaces can describe the various shapes of objects in JavaScript.
    In addition to describing common objects with attributes, interfaces can also describe function types.
    为了使用接口表示函数类型,我们需要给接口定义一个调用签名。
    它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。
    In order to use interfaces to represent function types, we need to define a call signature for
    the interface. It's like a function definition with only parameter lists and return value types.
    Each parameter in the parameter list needs a name and type.

    interface SearchFunc{
        (source:string,subString:string):boolean;
    }
    

    这样定义后,我们像使用其他接口意义使用这个函数型的接口
    如何创建一个函数类型的变量并将一个同类型函数赋值给这个变量
    With this definition, we use this functional interface in the sense of other interfaces.
    How to create a variable of function type and assign a function of the same type to the variable

    let mySearch:SearchFunc;
    mySearch=function(source:string,subString:string){
        let result=source.search(subString);
        if(result==-1){
            return false;
        }else{
            return true;
        }
    }
    

    对于函数类型的类型检查来说,函数的参数名不需要与接口里定义的名字相匹配
    For type checking of function types, the parameter name of a function
    does not need to match the name defined in the interface.

    let mySearch:SearchFunc;
    mySearch=function(src:string,sub:string):boolean{
        let result=src.search(sub);
        if(result==-1){
            return false;
        }else {
            return true;
        }
    }
    let mySearch:SearchFunc;
    mySearch=function(src,sub){
        let result=src.search(sub);
        if(result==-1){
            return false;
        }else{
            return true;
        }
    }
    

    可索引的类型
    Indexable types

    interface StringArray{
        [index:number]:string;
    // 这个索引签名表示了当用 number去索引StringArray时会得到string类型的返回值。
    //This index signature represents the return value of string type when StringArray is indexed with number.
    }
    let myArray:StringArray;
    myArray=["bob","tine"];
    let myStr:string=myArray[0];
    
    class Animal{
        name:string;
    }
    class Dog extends Animal{
        breed:string;
    }
    interface NotOkay{
        [x:number]:Animal;
        [x:string]:Dog;
    }
    

    字符串索引签名能够很好的描述dictionary模式,并且它们也会确保所有属性与其返回值类型相匹配。
    因为字符串索引声明了 obj.property和obj["property"]两种形式都可以。
    String indexed signatures describe dictionary patterns well, and they also ensure that all attributes
    match their return value types. Because the string index declares
    that both obj. property and obj ["property"] can be used.

    interface NumberDictionary{
        [index:string]:number;
        length:number;
        name:string;
    //name的类型不是索引类型的子类型
    //The type of name is not a subtype of the index type
    }
    

    将索引类型设置为只读,这样就防止了给索引赋值
    Setting the index type to read-only prevents index assignment

    interface ReadonlyStringArray{
        readonly [index:number]:string;
    }
    let myArray:ReadonlyStringArray=["Alice","Bob"];
    myArray[2]="Mallory";//error
    

    类类型
    Class type
    TypeScript也能够用它来明确的强制一个类去符合某种契约。
    TypeScript can also be used to explicitly force a class to conform to a contract.

    interface ClockInterface{
        currentTime:Date;
    }
    class Clock implements ClockInterface{
        currentTime:Date;
        constructor(h:number,m:number){}
    }
    

    在接口中描述一个方法,在类里实现它,如同下面的setTime方法一样:
    Describe a method in the interface and implement it in the class,
    just like the setTime method below:

    interface ClockInterface{
        currentTime:Date;
        setTime(d:Date);
    }
    class Clock implements ClockInterface{
        currentTime:Date;
        setTime(d:Date){
            this.currentTime=d;
        }
        constructor(h:number,m:number){}
    }
    

    接口描述了类的公共部分,而不是公共和私有两部分。 它不会帮你检查类是否具有某些私有成员。
    Interfaces describe the public part of a class, not the public and private parts.
    It doesn't help you check whether a class has some private members.
    类静态部分与实例部分的区别
    The Difference between Class Static Part and Example Part
    ColockConstuctor为构造函数所用
    ColockConstuctor for constructors
    ClockInterface为实例方法所用
    ClockInterface for instance methods

    interface ClockConstuctor{
        new(hour:number,minute:number):ClockInterface;
    }
    interface ClockInterface{
        tick();
    }
    function createClock(ctor:ClockConstuctor,hour:number,minute:number):
    ClockInterface{
        return new ctor(hour,minute);
    }
    class DigitalClock implements ClockInterface{
        constructor(h:number,m:number){}
        tick(){
            console.log("beep beep");
        }
    }
    class AnalogClock implements ClockInterface{
        constructor(h:number,m:number){}
        tick(){
            console.log("tick tock")
        }
    }
    let digital=createClock(DigitalClock,12,17);
    let analog=createClock(AnalogClock,7,32);
    

    扩展接口
    Extended interface

    interface Shape{
        color:string;
    }
    interface Square extends Shape{
        sideLength:number
    }
    let square=<Square>{};
    square.color="blue";
    square.sideLength=10;
    

    一个接口可以继承多个接口,创建出多个接口的合成接口
    An interface can inherit multiple interfaces and create a composite interface of multiple interfaces.

    interface Shape {
        color: string;
    }
    
    interface PenStroke {
        penWidth: number;
    }
    interface Square extends Shape,PenStroke{
        sideLength:number;
    }
    let square=<Square>{};
    square.color="blue";
    square.sideLength=10;
    square.penWidth=5.0;
    

    混合类型
    Mixed type
    一个对象可以同时作为函数和对象使用,并带有额外的属性
    An object can be used as both a function and an object with additional attributes

    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;
    

    接口继承类
    Interface inheritance class

    class Control {
        private state: any;
    }
    
    interface SelectableControl extends Control {
        select(): void;
    }
    
    class Button extends Control {
        select() { }
    }
    class TextBox extends Control {
        select() { }
    }
    class Image {
        select() { }
    }
    class Location {
        select() { }
    }
    
  • 相关阅读:
    android_handler(二)
    android_handler(一)
    java_synchronized 用法
    android surfaView surfaHolder video 播放
    《Java 8 实战》读书笔记
    Java面试宝典——基础部分
    Shell脚本---处理用户输入
    《Spring》(十八)---- 事务管理
    《Spring》(十七)---- JDBC访问数据
    《Spring》(十六)---- 基于Schema的AOP
  • 原文地址:https://www.cnblogs.com/smart-girl/p/10340236.html
Copyright © 2011-2022 走看看