Hello TypeScript experts.
I have the following code but I have to repeat the interface properties in the class otherwise I get:
Class incorrectly implements interface
When using an interface, is there a TypeScript shorthand for doing this without having to declare Id: number;
and all the other properties in the class? Thx
interface INavigation { Id: number; AppId: number; NavId: number; Name: string; ParentId: string; PageURL: string; Position: string; Active: string; Desktop: string; Tablet: string; Phone: string; RoleId: string; Target: string; } class Navigation implements INavigation { Id: number; AppId: number; NavId: number; Name: string; ParentId: string; PageURL: string; Position: string; Active: string; Desktop: string; Tablet: string; Phone: string; RoleId: string; Target: string; constructor(navigation: any) { this.Id = navigation.Id this.AppId = navigation.NavAppId this.NavId = navigation.NavId this.Name = navigation.NavName this.ParentId = navigation.NavParentId this.PageURL = navigation.NavPageURL this.Position = navigation.NavPosition this.Active = navigation.NavActive this.Desktop = navigation.NavDesktop this.Tablet = navigation.NavTablet this.Phone = navigation.NavPhone this.RoleId = navigation.NavRoleId this.Target = navigation.NavTarget } }
TypeScript - Class Implementing Interfaces. In TypeScript, a class can implement interfaces to enforce particular contracts (similar to languages like Java and C#).
We can also use interfaces to properly type classes created in JavaScript. To achieve this, we create an interface that contains the class’ properties and methods, then we use the implements keyword when creating our class. Note: Our interfaces describe the public side of the class rather than both the public and private side.
As with other JavaScript language features, TypeScript adds type annotations and other syntax to allow you to express relationships between classes and other types. Here’s the most basic class - an empty one:
Property 'name' has no initializer and is not definitely assigned in the constructor. Note that the field needs to be initialized in the constructor itself . TypeScript does not analyze methods you invoke from the constructor to detect initializations, because a derived class might override those methods and fail to initialize the members.
This is now possible in Typescript using class/interface merging.
interface Foo { a: number; } interface Baz extends Foo { } class Baz { constructor() { console.log(this.a); // no error here } }
https://github.com/Microsoft/TypeScript/issues/340#issuecomment-184964440
There is no built-in support for this.
We can however use a function that returns a class as the base type of our class. This function can lie a little bit and claim it implements the interface. We could also pass in some defaults for the members if necessary.
interface INavigation { Id: number; AppId: number; NavId: number; Name: string; ParentId: string; PageURL: string; Position: string; Active: string; Desktop: string; Tablet: string; Phone: string; RoleId: string; Target: string; } function autoImplement<T>(defaults?: Partial<T>) { return class { constructor() { Object.assign(this, defaults || {}); } } as new () => T } class Navigation extends autoImplement<INavigation>() { constructor(navigation: any) { super(); // other init here } }
If we want to have a base class, things get a bit more complicated since we have to perform a bit of surgery on the base type:
function autoImplementWithBase<TBase extends new (...args: any[]) => any>(base: TBase) { return function <T>(defaults?: Partial<T>): Pick<TBase, keyof TBase> & { new(...a: (TBase extends new (...o: infer A) => unknown ? A : [])): InstanceType<TBase> & T } { return class extends base { constructor(...a: any[]) { super(...a); Object.assign(this, defaults || {}); } } as any } } class BaseClass { m() { } foo: string static staticM() { } static staticFoo: string } class Navigation extends autoImplementWithBase(BaseClass)<INavigation>() { constructor(navigation: any) { super(); // Other init here } } Navigation.staticFoo Navigation.staticM new Navigation(null).m(); new Navigation(null).foo;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With