Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript automatically get interface properties in a class

Tags:

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   } } 
like image 835
danday74 Avatar asked Nov 03 '18 05:11

danday74


People also ask

What are interfaces in typescript?

TypeScript - Class Implementing Interfaces. In TypeScript, a class can implement interfaces to enforce particular contracts (similar to languages like Java and C#).

How to properly type classes created in JavaScript?

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.

What is a typescript class?

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:

What is the initializer of a property name in typescript?

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.


2 Answers

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

like image 89
SamB Avatar answered Oct 16 '22 06:10

SamB


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; 
like image 35
Titian Cernicova-Dragomir Avatar answered Oct 16 '22 06:10

Titian Cernicova-Dragomir