Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is `Account` a reserved word in TypeScript?

Tags:

typescript

I'm stumped. The following TypeScript code fails to compile with this error:

fails.ts(10,7): error TS2420: Class 'Account' incorrectly implements interface 'IAccount'.
  Property 'name' is optional in type 'Account' but required in type 'IAccount'.
fails.ts(11,3): error TS2403: Subsequent variable declarations must have the same type.  Variable 'id' must be of type 'string', but here has type 'number'.
fails.ts(11,3): error TS2687: All declarations of 'id' must have identical modifiers.
fails.ts(14,3): error TS2687: All declarations of 'name' must have identical modifiers.

But if I rename class Account to class Hello it doesn't fail. Am I going crazy? Does anyone else see the same behavior?

interface IObject {
  id: number;
  table_name: string;
};

interface IAccount extends IObject {
  user_id: number;
  name: string;
};
class Account implements IAccount {
  id: number;
  table_name: string = 'account';
  user_id: number;
  name: string;
};

I'm using TypeScript ^2.3.4

Here's a complete example with failing and non-failing code: https://gist.github.com/iffy/9d518d78d6ead2fe1fbc9b0a4ba1a31d

like image 854
iffy Avatar asked Dec 24 '22 17:12

iffy


1 Answers

The name Account is not a reserved word but it is defined as part of lib.d.ts:

/////////////////////////////
/// IE DOM APIs
/////////////////////////////

interface Account {
    rpDisplayName?: string;
    displayName?: string;
    id?: string;
    name?: string;
    imageURL?: string;
}

TypeScript performs declaration merging on your Account and the one in lib.d.ts and that causes the problem you get. If you turn your file into a module, your Account will be specific to your module and TypeScript will stop trying to combine it with the global one.

For instance, by adding export {}; you can trivially turn your file into a module:

interface IObject {
  id: number;
  table_name: string;
};

interface IAccount extends IObject {
  user_id: number;
  name: string;
};
class Account implements IAccount {
  id: number;
  table_name: string = 'account';
  user_id: number;
  name: string;
};

export {};
like image 124
Louis Avatar answered Jan 13 '23 20:01

Louis