Introducing override
keyword for this proposal. The keyword name is changeable.
var foo: T;
override foo = u; // u of arbitrary type U
override foo: TT; // TT that implements T
declare bar: T2;
override declare bar: V; // arbitrary type V, overriding global type declaration
This always works regardless of type compatibility.
var foo = t; // t of type T
override foo = u; // u of arbitrary type U
// `foo` now works as if it is declared as `U` type
var some = 3;
some = 'abc'; // Fails
override some = 'abc'; // Succeeds
some = 'efg'; // Succeeds
some = 5; // Fails
override some: number[] = []; // Succeeds
some = [4, 5, 6]; // Succeeds
some = 'string' // Fails
Type compatibilty checker works reversed here, to allow going lower in type hierarchy.
/*
This succeeds only when U implements T.
*/
var foo: T;
var bar: U; // U implements T;
override foo: U;
// `foo` now works as if it is declared as `U` type
var other: Blob;
override other: File; // Succeeds
override other: string; // Fails
var anything: any = getAnything();
if (typeof anything === 'string') {
override anything: string;
// `anything` now works as if it is declared as string type
// The new declaration works only in this block.
anything.split('');
}
//`anything` still works as `any` type here
This feature is provided for users to fix wrong or outdated type declarations while keeping existing external declaration files intact. Only one overriding is allowed for each declaration, to prevent collision among multiple overrides from multiple files. Globally overridden types are applied to all lines.
Users will be recommended to override global declarations only in the type libraries for this sole specific purpose.
Global type overriding does not require any type compatibility with originally declared type.
declare foo: T;
override declare foo: U;
override declare foo: V; // Error, the type of foo is already overridden.
override declare foo = 4; // Error, not allowed in ambient type declaration
Imagine that we are writing TypeScript code to polyfill HTML5.1 createImageBitmap function.
function createImageBitmap(input: any) {
if (input instanceof HTMLImageElement) {
var image: HTMLImageElement = input;
// ...
}
else if (input instanceof HTMLVideoElement) {
var video: HTMLVideoElement = input;
// ...
}
else if (input instanceof HTMLCanvasElement) {
var canvas: HTMLCanvasElement = input;
// ...
}
// ...
}
override
keyword would help here to remove those new variable declarations, while keeping type safety for lines below as much as possible.
function createImageBitmap(input: any) {
if (input instanceof HTMLImageElement) {
override input: HTMLImageElement;
// ...
}
else if (input instanceof HTMLVideoElement) {
override input: HTMLVideoElement;
// ...
}
else if (input instanceof HTMLCanvasElement) {
override input: HTMLCanvasElement;
// ...
}
// ...
}
function foo() {
override this: string;
}
This code is from jews project.
var time = $('#wrap_container_new .sub_tit_area .sub_data').text().split('/');
var date = new Date(time[0].replace(/\./g, '/'));
// TypeScript compiler will give an error here.
time = /([AP]M)\s*(\d\d):(\d\d)/i.exec(time[1]);
var hh = time[2] | 0;
var mm = time[3] | 0;
if (time[1].toUpperCase() === 'PM') hh += 12;
date.setHours(hh);
date.setMinutes(mm);
return {
created: date,
lastModified: undefined
};
This will help the line:
override time = /([AP]M)\s*(\d\d):(\d\d)/i.exec(time[1]);
override declare var MouseEvent: {
prototype: MouseEvent;
new(typeArg: string, mouseEventInitDict?: MouseEventInit): MouseEvent;
}