0

I'm trying to extend the jQuery unobtrusive validation interface with an additional method, but for some reason, it will not pick up the interface at all. The snippet below is a bare snippet I tried running in the TypeScript playground as a test, but it claims it "Cannot find name 'Validator'", which is odd, considering the snippet follows the general syntax for augmenting a type in TypeScript, and the exact same syntax does work in this answer.

interface Validator {
    parseDynamicContent: (selector: string) => void;
}

Validator.prototype.parseDynamicContent = function (selector: string): void {

}

Am I doing something wrong, or is TypeScript broken... again?

Community
  • 1
  • 1
Tom Lint
  • 483
  • 5
  • 13

1 Answers1

0

Interfaces are not translated into JavaScript code. They only exist during compilation for type-checking. You cannot extend a constructor function that doesn't exist.The usual way to go about it would be to create a class that implements Validator.

Now, while TypeScript doesn't allow the merging of classes and interfaces, it does allow merging a var with an interface, and the var can contain an implementation of Validator. Here's how it works:

export interface Validator {
    parseDynamicContent: (selector: string) => void;
}

Then create an implementing class. You can keep that one hidden, unless you want other classes to extend its behavior.

class ValidatorImpl implements Validator {
    constructor() {}
    parseDynamicContent: (selector: string) => void;
}

Now you create the var to merge with the interface. The var will have a type that matches the static side of ValidatorImpl, which includes the constructor and all member explicitly declared static of coure. This variable will have the implementing class assigned to it:

var Validator: {
    new(): Validator;
} = ValidatorImpl;

Recall that under the hood a class is a constructor function, which is why the assignment is compatible. Put together into a single file, the code fragments above compile into this:

var ValidatorImpl = (function () {
    function ValidatorImpl() {
        this.parseDynamicContent = null;
    }
    return ValidatorImpl;
})();
var Validator = ValidatorImpl;

So you get your cake and get to eat it :D . You can implement Validator in classes derived from ValidatorImpl or from scratch, or forget about classes altogether -- any record you create on the fly that contains a member parseDynamicContent with the correct type will be accepted wherever Validators are expected.

Hope that helps.