program tip

TypeScript 인터페이스에서 정적 속성을 정의하는 방법

radiobox 2020. 9. 12. 09:22
반응형

TypeScript 인터페이스에서 정적 속성을 정의하는 방법


typescript 인터페이스 에서 정적 속성 을 선언하고 싶 습니까? 나는 이것에 대해 아무데도 찾지 못했습니다.

interface myInterface {
  static Name:string;
}

가능할까요?


TypeScript에서 인터페이스에 대한 정적 속성을 정의 할 수 없습니다.

Date의 정의에 추가하는 대신 객체 를 변경하고 싶다고 가정 해보면 객체를 Date래핑하거나 단순히 리치 날짜 클래스를 만들어 Date하지 않는 작업을 수행 할 수 있습니다.

class RichDate {
    public static MinValue = new Date();
}

Date는 TypeScript의 인터페이스이기 때문에 extends키워드를 사용하여 클래스로 확장 할 수 없습니다 . 날짜가 클래스 인 경우 좋은 솔루션이 될 수 있으므로 조금 아쉽습니다 .

MinValue프로토 타입에 속성 을 제공하기 위해 Date 객체를 확장하려는 경우 다음을 수행 할 수 있습니다.

interface Date {
    MinValue: Date;
}

Date.prototype.MinValue = new Date(0);

다음을 사용하여 호출 :

var x = new Date();
console.log(x.MinValue);

인스턴스없이 사용할 수 있도록하려면 할 수 있습니다.하지만 약간 까다 롭습니다.

interface DateStatic extends Date {
    MinValue: Date;
}

Date['MinValue'] = new Date(0);

다음을 사용하여 호출 :

var x: DateStatic = <any>Date; // We aren't using an instance
console.log(x.MinValue);

@Duncan의 @Bartvds의 답변을 따르십시오. 몇 년이 지난 후에도 실행 가능한 방법을 제공하십시오.

Typescript 1.5가 출시 된 후 (@Jun 15 '15)이 시점에서 유용한 인터페이스

interface MyType {
    instanceMethod();
}

interface MyTypeStatic {
    new():MyType;
    staticMethod();
}

데코레이터의 도움으로 이런 식으로 구현할 수 있습니다.

/* class decorator */
function staticImplements<T>() {
    return <U extends T>(constructor: U) => {constructor};
}

@staticImplements<MyTypeStatic>()   /* this statement implements both normal interface & static interface */
class MyTypeClass { /* implements MyType { */ /* so this become optional not required */
    public static staticMethod() {}
    instanceMethod() {}
}

github open issue 13462 에서 내 의견을 참조하십시오 .

시각적 결과 : 정적 메서드 누락에 대한 힌트가있는 컴파일 오류입니다. 여기에 이미지 설명 입력

정적 메서드 구현 후 메서드 누락에 대한 힌트. 여기에 이미지 설명 입력

정적 인터페이스와 일반 인터페이스가 모두 충족 된 후 컴파일이 전달되었습니다. 여기에 이미지 설명 입력


정적 속성은 일반적으로 개체의 (전역) 생성자에 배치되는 반면 "interface"키워드는 개체의 인스턴스에 적용됩니다.

The previous answer given is of course correct if you are writing the class in TypeScript. It may help others to know that if you are describing an object that is already implemented elsewhere, then the global constructor including static properties can be declared like this:

declare var myInterface : {
  new(): Interface;
  Name:string;
}

You can define interface normally:

interface MyInterface {
    Name:string;
}

but you can't just do

class MyClass implements MyInterface {
    static Name:string; // typescript won't care about this field
    Name:string;         // and demand this one instead
}

To express that a class should follow this interface for its static properties you need a bit of trickery:

var MyClass: MyInterface;
MyClass = class {
    static Name:string; // if the class doesn't have that field it won't compile
}

You can even keep the name of the class, TypeScript (2.0) won't mind:

var MyClass: MyInterface;
MyClass = class MyClass {
    static Name:string; // if the class doesn't have that field it won't compile
}

If you wan't to inherit from many interfaces statically you'll have to merge them first into a new one:

interface NameInterface {
    Name:string;
}
interface AddressInterface {
    Address:string;
}
interface NameAndAddressInterface extends NameInterface, AddressInterface { }
var MyClass: NameAndAddressInterface;
MyClass = class MyClass {
    static Name:string; // if the class doesn't have that static field code won't compile
    static Address:string; // if the class doesn't have that static field code won't compile
}

Or if you don't want to name merged interface you can do:

interface NameInterface {
    Name:string;
}
interface AddressInterface {
    Address:string;
}
var MyClass: NameInterface & AddressInterface;
MyClass = class MyClass {
    static Name:string; // if the class doesn't have that static field code won't compile
    static Address:string; // if the class doesn't have that static field code won't compile
}

Working example


@duncan's solution above specifying new() for the static type works also with interfaces:

interface MyType {
    instanceMethod();
}

interface MyTypeStatic {
    new():MyType;
    staticMethod();
}

If you're looking to define a static class (ie. all methods/properties are static), you can do something like this:

interface MyStaticClassInterface {
  foo():string;
}

var myStaticClass:MyStaticClassInterface = {
  foo() {
    return 'bar';
  }
};

In this case, the static "class" is really just a plain-ol'-js-object, which implements all the methods of MyStaticClassInterface


You can merge interface with namespace using the same name:

interface myInterface { }

namespace myInterface {
  Name:string;
}

But this interface is only useful to know that its have property Name. You can not implement it.


I found a way to do this (without decorators) for my specific use case.

The important part that checks for static members is IObjectClass and using cls: IObjectClass<T> in the createObject method:

//------------------------
// Library
//------------------------
interface IObject {
  id: number;
}
interface IObjectClass<T> {
  new(): T;
  table_name: string;
}
function createObject<T extends IObject>(cls: IObjectClass<T>, data:Partial<T>):T {
  let obj:T = (<any>Object).assign({},
    data,
    {
      id: 1,
      table_name: cls.table_name,
    }
  )
  return obj;
}

//------------------------
// Implementation
//------------------------
export class User implements IObject {
  static table_name: string = 'user';
  id: number;
  name: string;
}

//------------------------
// Application
//------------------------
let user = createObject(User, {name: 'Jimmy'});
console.log(user.name);

Static modifiers cannot appear on a type member (TypeScript error TS1070). That's why I recommend to use an abstract class to solve the mission:

Example

// Interface definition
abstract class MyInterface {
  static MyName: string;
  abstract getText(): string;
}

// Interface implementation
class MyClass extends MyInterface {
  static MyName = 'TestName';
  getText(): string {
    return `This is my name static name "${MyClass.MyName}".`;
  }
}

// Test run
const test: MyInterface = new MyClass();
console.log(test.getText());

Yes, it is possible. Here is the solution

export interface Foo {

    test(): void;
}

export namespace Foo {

    export function statMethod(): void {
        console.log(2);
    }

}

참고 URL : https://stackoverflow.com/questions/13955157/how-to-define-static-property-in-typescript-interface

반응형