Reputation: 42229
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
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
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