Matthew Layton
Matthew Layton

Reputation: 42229

TypeScript static interface binding

I've asked a couple of questions related to extending static functionality of existing objects in JavaScript (using TypeScript). For the sake of all examples here, I am using Object

The following code demonstrates a polyfill definition for ECMAScript's Object.is function

Object.is = function(value1: any, value2: any): boolean {
    // ....impl
};  // ERROR : Property 'is' does not exist on type...

The reason for this is because is has not been implemented on Object, but we can make it visible like so

declare var Object: {
    is(value1: any, value2: any): boolean;
}

However the issue with this code is that this overwrites any existing static bindings (bind, call, create, freeze etc).

I understand that with recent versions of TypeScript, we can now statically bind interfaces which are open-ended to object declarations:

interface _Object {
    is(value1: any, value2: any): boolean;
}

declare var Object: _Object;

This is great because as pointed out, interfaces in TypeScript are open ended, thus I can continually bind more and more functionality into Object, however this does not correct the issue that once the interface is bound to Object, it overwrites the existing declaration, because lib.d.ts still declares Object like so:

declare var Object: {
    new (value?: any): Object;
    (): any;
    (value: any): any;
    prototype: Object;
    getPrototypeOf(o: any): any;
    getOwnPropertyDescriptor(o: any, p: string): PropertyDescriptor;
    getOwnPropertyNames(o: any): string[];
    create(o: any, properties?: PropertyDescriptorMap): any;
    defineProperty(o: any, p: string, attributes: PropertyDescriptor): any;
    defineProperties(o: any, properties: PropertyDescriptorMap): any;
    seal(o: any): any;
    freeze(o: any): any;
    preventExtensions(o: any): any;
    isSealed(o: any): boolean;
    isFrozen(o: any): boolean;
    isExtensible(o: any): boolean;
    keys(o: any): string[];
}

What I feel is needed here for the code in lib.d.ts to be refactored to allow open ended interfaces to be bound statically to declarations, like so

interface _Object {
    new (value?: any): Object;
    (): any;
    (value: any): any;
    prototype: Object;
    getPrototypeOf(o: any): any;
    getOwnPropertyDescriptor(o: any, p: string): PropertyDescriptor;
    getOwnPropertyNames(o: any): string[];
    create(o: any, properties?: PropertyDescriptorMap): any;
    defineProperty(o: any, p: string, attributes: PropertyDescriptor): any;
    defineProperties(o: any, properties: PropertyDescriptorMap): any;
    seal(o: any): any;
    freeze(o: any): any;
    preventExtensions(o: any): any;
    isSealed(o: any): boolean;
    isFrozen(o: any): boolean;
    isExtensible(o: any): boolean;
    keys(o: any): string[];
}

declare var Object: _Object;

Thus, when I create my interface for Object.is, and it's accompanying function, everything should work in harmony <--- excuse the pun, (ECMAScript 6 code name)

What I would like to know is, are there any plans fore future releases of TypeScript which will fix this issue, as suggested (or indeed any fixes which prove more efficient)?

Upvotes: 0

Views: 2334

Answers (2)

Stefan Born
Stefan Born

Reputation: 750

Since TypeScript 1.4 static extensions can be added easily. The TypeScript team changed the lib.d.ts file to use interfaces for all static type definitions.

The static type definitions are all named like [Type]Constructor: So if you want to add a static function to type Object, then add your definition to ObjectConstructor.

Definition:

interface ObjectConstructor
{
    is(value1: any, value2: any): boolean;
}

Implementation:

Object.is = function(value1: any, value2: any): boolean
{
    // your implementation here
}

Upvotes: 2

basarat
basarat

Reputation: 276269

What I would like to know is, are there any plans fore future releases of TypeScript which will fix this issue, as suggested (or indeed any fixes which prove more efficient)?

Already raised here : https://github.com/Microsoft/TypeScript/issues/182

Upvotes: 0

Related Questions