强制自定义JavaScript以遵守TypeScript接口

时间:2016-09-06 23:29:31

标签: typescript

给出以下接口:

interface Person {
    constructor: Function;
    getFullName(): string;
}

interface PersonConstructor {
    new (firstName: string, lastName: string): Person;
    prototype: Person;
    createPerson(firstName: string, lastName: string): Person;
}

我想使用JS而不是TS来自定义编写类,如下所示:

var Person = (() => {
    function Person(firstName: string, lastName: string) {
        var _firstName = firstName;
        var _lastName = lastName;

        this.getFullName = () => _firstName + " " + _lastName;
    }

    Person.createPerson = (firstName: string, lastName: string): Person => new Person(firstName, lastName);

    return Person;
})();

但是我收到以下错误:

  

财产' createPerson'类型'(firstName:string,   lastName:string)=>空隙'

我还希望能够将我的自定义JS用作TypeScript中的基类...

class FamousPerson extends Person {

}

但是我得到了这个错误...

  

键入'(firstName:string,lastName:string)=>空隙'不是一个   构造函数类型。

如何让我的自定义JS尊重我的界面?

注意:接口遵循TS 1.4中采用的相同构造函数(静态接口)模式

2 个答案:

答案 0 :(得分:1)

你可以使它工作,但有些使用any

interface Person {
    getFullName(): string;
}

interface PersonConstructor {
    new (firstName: string, lastName: string): Person;
    prototype: Person;
    createPerson(firstName: string, lastName: string): Person;
}

var Person = (function(): PersonConstructor {
    function Person(firstName: string, lastName: string) {
        var _firstName = firstName;
        var _lastName = lastName;

        this.getFullName = () => _firstName + " " + _lastName;
    }

    (Person as any).createPerson = (firstName: string, lastName: string): Person => new Person(firstName, lastName);

    return Person as any;
})();

code in playground

您的代码更改:

  1. constructor界面
  2. 中删除了Person
  3. 声明实际的构造函数闭包返回PersonConstructor
  4. 在添加Person功能和退回时将any投射到createPerson
  5. 虽然这适用于您的第一个请求,但如果您打算覆盖Person类方法,则会遇到第二个请求。 例如:

    class User extends Person {
        constructor(firstName: string, lastName: string) {
            super(firstName, lastName);
    
            console.log(this.getFullName());
        }
    
        getFullName(): string {
            return "user: " + super.getFullName();
        }
    }
    

    创建新的User会记录:"first last"而不是"user: first last"这是因为User.getFullName是在原型上定义的,但后来又在{被新定义覆盖的Person 在编译的js代码中可以更清楚地看到:

    var Person = (function () {
        function Person(firstName, lastName) {
            var _firstName = firstName;
            var _lastName = lastName;
            this.getFullName = function () { return _firstName + " " + _lastName; };
        }
        Person.createPerson = function (firstName, lastName) { return new Person(firstName, lastName); };
        return Person;
    })();
    var User = (function (_super) {
        __extends(User, _super);
        function User(firstName, lastName) {
            _super.call(this, firstName, lastName);
            console.log(this.getFullName());
        }
        User.prototype.getFullName = function () {
            return "user: " + _super.prototype.getFullName.call(this);
        };
        return User;
    }(Person));
    

    code in playground

    能够覆盖方法的唯一方法(没有经过很多麻烦)是它们是在原型上而不是在实例上实现的。
    但这将剥夺使用"私人会员的能力。你用var定义,我认为这是你想要开始这样做的原因。

答案 1 :(得分:0)

  1. Person.createPerson替换为“人[' createPerson']

  2. 您无法在JS中扩展自定义写入类。 TypeScript不会理解var Person是一个类。你有什么理由不能在TS写课吗?