Programing

형식 지정자가 클래스의 인터페이스 속성을 자동으로 가져오기

c10106 2022. 4. 9. 09:48
반응형

형식 지정자가 클래스의 인터페이스 속성을 자동으로 가져오기

안녕 TypeScript 전문가들.

다음 코드가 있지만 그렇지 않으면 수업에서 인터페이스 속성을 반복해야 한다.

클래스가 인터페이스를 잘못 구현함

인터페이스를 사용할 때 TypeScript를 신고할 필요 없이 이렇게 하는 속기가 있는가?Id: number;그리고 다른 모든 수업들은?고마워

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
  }
}

이것은 이제 클래스/인터페이스 병합 기능을 사용하여 Typecript에서 가능하다.

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

이것에 대한 내재된 지원은 없다.

그러나 우리는 클래스를 반환하는 함수를 우리 클래스의 기본 유형으로 사용할 수 있다.이 기능은 조금 누워 인터페이스를 구현한다고 주장할 수 있다.우리는 또한 필요하다면 회원들의 채무 불이행도 처리할 수 있다.

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
  }
}

베이스 클래스를 하려면 베이스 타입으로 수술을 해야 하기 때문에 일이 좀 더 복잡해진다.

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;

클래스/인터페이스 병합과 생성자에서 Object.assign을 사용하여 생성자에서 긴 할당을 방지하기 위해 두 답변 간의 혼합:

interface Foo {
    a: number;
    b: number;
}

interface Baz extends Foo { }

class Baz  {
    c: number = 4

  constructor (foo: Foo) {
    Object.assign(this, foo, {})
  }
  
  getC() {
    return this.c
  }
}

let foo: Foo = {
    a: 3,
    b: 8
}

let baz = new Baz(foo)
// keep methods and properties
console.warn(baz)

클래스 선언은 인터페이스를 명시적으로 구현해야 한다.

참조URL: https://stackoverflow.com/questions/53128744/typescript-automatically-get-interface-properties-in-a-class

반응형