programing

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

newstyles 2023. 3. 20. 21:42

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

타이프 스크립트인터페이스에 정적 속성을 선언하고 싶습니다.나는 이것에 대해 어디에서도 찾지 못했다.

interface myInterface {
  static Name:string;
}

가능합니까?

@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() {}
}

기트허브 13462호에서 제 의견을 참고하세요.

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

정적 메서드가 구현되면 메서드에 대한 힌트가 누락됩니다.여기에 이미지 설명 입력

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

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

를 들어 '', '바꾸고 싶다'고 하면 .Date ""의 에 것이 ""의 정의에 추가하려고 .Date, 당신은 그것을 포장할 수도 있고 단순히 당신의 리치 날짜 클래스를 만들 수도 있습니다.Date아, 아, 아, 아, 아, 아, 아, 아, 아, 아.

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

이므로 Date TypeScript를 수 .extends키워드입니다.날짜가 클래스라면 이 방법이 좋을 것 같기 때문에 조금 아쉽습니다.

하여 Date를 하는 MinValue을 사용하다

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);

유형 멤버에는 정적 수식자가 표시될 수 없습니다(TypeScript 오류 TS1070).그렇기 때문에 추상적인 클래스와 상속을 사용하여 미션을 해결할 것을 권장합니다.

// 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());

인터페이스는 통상적으로 정의할 수 있습니다.

interface MyInterface {
    Name:string;
}

그냥 할 수는 없어요.

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

클래스가 스태틱 속성에 대해 이 인터페이스를 따라야 함을 나타내려면 약간의 속임수가 필요합니다.

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

클래스 이름도 유지할 수 있습니다.TypeScript(2.0)는, 다음의 점에 주의해 주세요.

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

많은 인터페이스로부터 정적으로 상속하는 경우는, 우선 그것들을 새로운 인터페이스에 Marge 할 필요가 있습니다.

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
}

또는 Marge된 인터페이스에 이름을 붙이지 않는 경우는, 다음의 조작을 실행할 수 있습니다.

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
}

작업

스태틱 속성은 보통 객체의 (글로벌)컨스트럭터에 배치되지만 "interface" 키워드는 객체의 인스턴스에 적용됩니다.

TypeScript로 클래스를 작성할 경우 앞의 답변은 물론 정확합니다.다른 곳에서 이미 구현되어 있는 개체를 설명하는 경우 정적 속성을 포함하는 글로벌컨스트럭터가 다음과 같이 선언될 수 있음을 알아두면 도움이 될 수 있습니다.

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

솔루션

""를 합니다.I '''를 확인합니다.C를 확장하다I:

type StaticImplements<I extends new (...args: any[]) => any, C extends I> = InstanceType<I>;

인스턴스 메서드를 사용하는 인터페이스:

interface MyInstance {
    instanceMethod();
}

스태틱 메서드와의 인터페이스:

interface MyClassStatic {
    new (...args: any[]): MyInstance;
    staticMethod();
}

정적 메서드가 필요하고 자체 메서드로 확장해야 하는 클래스:

class MyClass implements StaticImplements<MyClassStatic, typeof MyClass> {
    static staticMethod();
    static ownStaticMethod();
    instanceMethod();
    ownInstanceMethod();
}

추리

인터페이스에서의 스태틱 방식의 정의에 대해서는 #33892에서, 추상 스태틱 방식에 대해서는 #34516에서 설명하고 있습니다.

Val과 Aleksey의 답변(감사합니다)을 바탕으로 이 솔루션은 다음과 같습니다.

  • 추가 런타임 값 필요 없음
  • 클래스 자체 구성원 정보가 보존됩니다.
  • 생성자 제약 조건을 허용합니다.

시험

현재 상태 - Playground 링크:

MyClass.staticMethod(); // OK
MyClass.ownStaticMethod(); // OK
new MyClass().instanceMethod(); // OK
new MyClass().ownInstanceMethod(); // OK

" " " 를 삭제할 staticMethod부에서MyClass- Playground 링크:

class MyClass implements StaticImplements<MyClassStatic, typeof MyClass> {} // Type 'typeof MyClass' does not satisfy the constraint 'MyClassStatic'. Property 'staticMethod' is missing in type 'typeof MyClass' but required in type 'MyClassStatic'.

If to remove 삭제할 경우instanceMethod부에서MyClass- Playground 링크:

class MyClass implements StaticImplements<MyClassStatic, typeof MyClass> {} // Class 'MyClass' incorrectly implements interface 'MyInstance'. Property 'instanceMethod' is missing in type 'MyClass' but required in type 'MyInstance'.

@duncan's solution above specifying @params의 솔루션 지정new() for the static type works also with interfaces:static 타입의 경우는, 인터페이스에서도 동작합니다.

interface MyType {
    instanceMethod();
}

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

여기서 언급하지 않은 다른 옵션은 스태틱인터페이스를 나타내는 유형을 사용하여 변수를 정의하고 변수에 클래스 식을 할당하는 것입니다.

interface MyType {
    instanceMethod(): void;
}

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

// ok
const MyTypeClass: MyTypeStatic = class MyTypeClass {
    public static staticMethod() { }
    instanceMethod() { }
}

// error: 'instanceMethod' is missing
const MyTypeClass1: MyTypeStatic = class MyTypeClass {
    public static staticMethod() { }
}

// error: 'staticMethod' is missing
const MyTypeClass2: MyTypeStatic = class MyTypeClass {
    instanceMethod() { }
}

효과는 데코레이터와 동일하지만 데코레이터의 오버헤드는 없습니다.

놀이터.

GitHub 관련 제안/토론

상위 정답이 너무 복잡해서 좀 놀랐어요!하지만 아마도 그것은 이 실이 너무 오래되었기 때문일 것이다.

편집: 실제로 몇 가지 테스트 결과, 당초의 시도는 거의 무효가 되어 버렸습니다만, 이 문제는 당초 예상했던 것보다 다소 대처하기 어려운 것이 판명되었습니다.

하지만, 1시간 정도 손질한 결과, 지금까지 (처음 아이디어를 바탕으로) 가장 좋고 깨끗한 해결책을 찾은 것 같습니다!제시된 질문이 "인터페이스에 정적 속성을 포함하려면 어떻게 해야 합니까?"라면 이는 상당히 적절한 답변이라고 생각합니다.적어도 인터페이스(컴파일 시간 입력/요건/제한)만 필요한 경우에는 클래스를 확장하는 것보다 낫습니다.이 솔루션도 100% 환경이기 때문에 (1개의 작은 솔루션과 달리) 실질적인 단점은 없습니다.extends및 없이 선언 구문을 할 때 ). 기반 클래스 확장자) classes는 classes를 사용합니다.이로 인해 런타임 오버헤드가 발생하지 않으며 런타임 클래스 상속이 필요하지 않습니다.클래스 전체(스태틱멤버와 비스태틱멤버 모두)를 1개의 인터페이스로 정의할 수 있습니다.

이렇게 하는 거야!

/** ./interface.ts */
// In a file module (best), or wrap in ts module or namespace block

// Putting this in a module provides encapsulation ensuring that no one is
// at risk of misusing this class (it must be used as a type only). 

// Export only a type reference which will make it error is someone tries 
// to use it as a value (such as in an `extends` clause, or trying to 
// instantiate it).

/** 
 * Other Ideas For Names To Differentiate From Actual Classes/Non-Ambient Values:
 * MyClassInterface or _Interface_MyClass or MyClass_Interface or Interface_MyClass  
 **/
declare class _MyClassInterface {
    static staticProp: string;
    static staticMethod(): number;
    readonly prop: boolean 
    /** 
     * Note: Above, readonly won't need to be specified in the real class 
     * but the prop *will* still be readonly anyway.
     *
     * Now for the only caveat!
     * It does appear however that you cannot mark anything private or 
     * protected in this pseudo-interface which is a bummer, only props
     * and methods that appear only in the real class can be.
     */
    prop2: boolean;
    method(): Function;
    constructor(p1: string, p2: number);
}

export type MyClassInterface = typeof _MyClassInterface;

이제 인터페이스를 소비합니다.

/** ./consumer.ts */
import { MyClassInterface } from "./interface" // type import

const MyClass: MyClassInterface = class {
    static staticProp: string;
    prop: boolean;
    prop2: boolean;
    protected onlyOnRealClass: boolean; /* this is ok since this prop doesn't exist on the interface */

    static staticMethod() {
        return 5;
    }

    method() {
        return () => {};
    }

    constructor(p1: string, p2: number) {}
};

해 주십시오.typeof여기서 키워드는 꼭 필요합니다(제 기억대로라면, typescript가 없으면 정말 필요한 것은 클래스 자체의 유형일 때 typescript가 인스턴스 유형을 지정한다고 생각하기 때문입니다).를 들어, 우리가 할 때,

const a: MyClass = new MyClass()

를 제외하고typeof즉 "" "" " " " " " " " 입니다.aMyClass 자체가 아니라 MyClass 인스턴스여야 합니다.

abstract실수로 수업을 인스턴스화하려고 하지 않도록...

추상적: 추상적실제 클래스는 실제 환경 클래스에서 추상적인 속성을 상속하기 때문입니다(감각적으로 인식됨). 인스턴스화된 ts .만약 주변 클래스가 실수로 인스턴스화 되어도 오류가 발생하지 않도록 해야 합니다. 주변 을 붙이거나 .Interface하고 있습니다.이후 이 문제에 대처하기 위해 인터페이스를 파일모듈에 캡슐화하여 다른 모든 코드에 비공개로 만들고 유형 참조만 내보냅니다.

그게 전부야!

인터페이스를 모듈에 넣는 것이 꼭 필요한 것은 아니지만 다음과 같은 몇 가지 작은 이점이 있습니다.

  1. 전체에서 되는 "은 키워드 "type-information"을 하지 않기 .typeof

  2. 랩된 주변 클래스/인터페이스 선언과는 달리 내보내기/경향 식별자는 엄밀하게 유형(유형)이기 때문에 이를 인스턴스화하거나 extends 구에서 사용하려고 하면 오류가 발생합니다(또는 런타임 값이 예상되는 다른 곳에서 사용).

이 예에서는 클래스 식에 클래스 이름을 제공하지 않습니다. 클래스 식도 모든 함수 식과 마찬가지로 클래스 이름이 제공되지 않은 경우 할당된 식별자만 상속되기 때문입니다.따라서 ID가 해당 클래스 또는 함수에 대해 원하는 이름과 동일한 경우 해당 ID를 끄면 됩니다.또는 보통과 같이 1개의 인라인을 제공해도 ID보다 우선합니다.클래스 또는 함수 이름은 함수/클래스를 만든 후에도 변경할 수 있지만 Object.defineProperty 또는 Object.defineProperties를 통해서만 변경할 수 있습니다.

는 'FWIW'로 할 수 .implemented(최소한 최신 버전의 TS에서는) 다른 클래스에 의해 설정되지만 정적 속성은 무시됩니다.implementing anything only applies to the 모든 것이 적용되는 것은prototype두 방향에서쌍방향으로

정적 클래스(즉, 모든 메서드/속성이 정적)를 정의하려는 경우 다음과 같은 작업을 수행할 수 있습니다.

interface MyStaticClassInterface {
  foo():string;
}

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

이 경우, 정적 '클'는 이 우 브 든 태 젝 서 플 " 레일"- in this "'object, the casejsol- the isclass는 of실MyStaticClassInterface

같은 이름을 사용하여 인터페이스를 네임스페이스와 병합할 수 있습니다.

interface myInterface { }

namespace myInterface {
  Name:string;
}

그러나 이 인터페이스는 재산 나 터 이 인 성 다 을 아 니 다 interface도 but this됩이 is property useful have움 that to its알것있야속는그 only이Name. 당신은 그것을 구현할 수 없습니다.구현할 수 없습니다.

네, 가능합니다.여기 해결책이 있습니다.

export interface Foo {

    test(): void;
}

export namespace Foo {

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

}

다음은 매우 간단한 방법입니다.

interface MyClass {
    new (): MyClassInstance;
    staticMethod(): string;
}

interface MyClassInstance {
    instanceMethod(): string;
}

const Class: MyClass = class {
    static staticMethod() {
        return "This is a static method";
    }
    instanceMethod() {
        return "This is an instance method";
    }
}

Class.staticMethod();

// Has type MyClassInstance
const instance = new Class();
instance.instanceMethod();

이것에 의해, 클래스가 통상대로 인터페이스를 확장할 수 있는 것은 아닙니다만, 대부분의 경우 이것으로 충분합니다.

내 특정 사용 사례에 맞게 (장식사가 필요 없는) 방법을 찾았습니다.

The important part that checks for static members is 스태틱 멤버를 체크하는 중요한 부분은IObjectClass and and를 합니다.cls: IObjectClass<T> createObject★★★★

//------------------------
// 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);

Typescript 인터페이스에서는 static 키워드가 지원되지 않지만 스태틱멤버를 가진를 작성하면 가능합니다.

다음 코드에서는 2개의 정적 멤버와 printSerial을 가진 함수 인터페이스를 만들었습니다.

// factory is a function interface
interface Factory<T> {
    (name: string, age: number): T;

    //staic property
    serialNumber: number;

    //static method
    printSrial: () => void;
}

class Dog {
    constructor(public name: string, public age: number) { }
}

const dogFactory: Factory<Dog> = (name, age) => {
    return new Dog(name, age);
}

// initialising static members

dogFactory.serialNumber = 1234;
dogFactory.printSrial = () => console.log(dogFactory.serialNumber);


//instance of Dog that DogFactory creates
const myDog = dogFactory("spike", 3);

//static property that returns 1234
console.log(dogFactory.serialNumber)

//static method that prints the serial 1234
dogFactory.printSrial();

다른 솔루션들은 적절한 경로에서 벗어난 것 같습니다.제 시나리오가 아래의 Typescript 문서에서 다루어졌음을 알 수 있었습니다.

interface AppPackageCheck<T> {
  new (packageExists: boolean): T
  checkIfPackageExists(): boolean;
}

class WebApp {
    public static checkIfPackageExists(): boolean {
        return false;
    }

    constructor(public packageExists: boolean) {}
}

class BackendApp {
    constructor(public packageExists: boolean) {}
}

function createApp<T>(type: AppPackageCheck<T>): T {
    const packageExists = type.checkIfPackageExists();
    return new type(packageExists)
}

let web = createApp(WebApp);

// compiler failure here, missing checkIfPackageExists
let backend = createApp(BackendApp); 

Winterhotlatte는 나를 올바른 방향으로 이끌 수 있는 좋은 답을 가지고 있었다.
단, 스태틱인터페이스에 컨스트럭터를 강제로 포함시키는 것은 매우 불편합니다.

간이판

연장을 반전시키면 다음과 같은 이점이 있습니다.

type Static<TClass extends IStaticInterface & { new(...args) }, IStaticInterface>
  = InstanceType<TClass>;

인터페이스에 컨스트럭터를 추가할 필요가 없습니다.

interface IMeow { readonly IsMeow: boolean; }

그리고 이렇게 편리하게 사용:

class Cat implements Static<typeof Cat, IMeow> {
  readonly static IsMeow = true;
}

이전과 마찬가지로, 만약 그렇다면 매우 명백한 오류가 발생합니다.static IsMeow되어 있다Cat
또한 모든 면에서 여전히 정상적으로 작동하기 전처럼.

뛰어난 가독성(주관적)

다음 유형 뒤에 "implements" 문자열이 필요합니다.

type Static<TClass extends IStaticInterface & { new(...args) },
  _txt extends "implements", IStaticInterface>
  = InstanceType<TClass>;

여기에 우리의 고양이가 있습니다.

class Cat implements Static<typeof Cat, "implements", IMeow> {
  static readonly IsMeow = true;
}

복수 결합(과도한)

정말 없어요, 요. 그냥 반복하면 돼.Static<...> 됩니다: ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ.

type Static<TClass extends InterfacesCombined & { new(...args) }, _txt extends "implements",
  IStaticInterface, IStatic2 = {}, IStatic3 = {}, IStatic4 = {}, IStatic5 = {},
  InterfacesCombined extends IStaticInterface & IStatic2 & IStatic3 & IStatic4 & IStatic5
    = IStaticInterface & IStatic2 & IStatic3 & IStatic4 & IStatic5>
  = InstanceType<TClass>;

보다 복잡한 방법으로 Cat을 업그레이드해 보겠습니다.

interface IPurr { purr(): string; }
interface ILick { Lick(human: any): void; }

사용법은 다음과 같습니다.

class Cat implements IPurr, Static<typeof Cat, "implements", IMeow, ILick> {
  static readonly IsMeow = true;
  static Lick(human: any) { /* obey me homan! */ }
  
  purr() { return "Prrrrr"; }
}

콘크리트 정적 인터페이스

자주 는, 그 모든 Static<... 거. ㅎㅎㅎ
먼저 이 작은 도우미를 제거합시다.

type New<T> = { new(...args: any): T };

스태틱을 "ILick★★★★★★★★★★★★★★★★★★:

type IStaticLick<TClass extends ILick & New<InstanceType<TClass>> = InstanceType<TClass>;

Voila:

class Cat2 implements IStaticLick<typeof Cat2> {
  static Lick(human: any) { /* obey me homan! */ }
}

실제로 무슨 일이 일어나고 있는 거죠?

는 단지 '일부러'를 뿐이다.typeof T 「 interface하고 있습니다.

만약 '만약에'가interface IFoo { stuff }+class Foo implements IFoo라고 말하다Foo is "stuff" 우리가 것은 '우리'는 '우리 '우리'는 '우리'가 아니라 '우리'가'"stuff" must be in T for T to be allowed inside Static<T, ...>.

그...implementsclass Foo implements Static<...>그냥 우리 멋진 것을 있다는 .< ''''>""""""""""""""" VIP!

즉, 다음과 같이 쓸 수 있습니다.

class FakeCat implements IStaticLick<typeof Cat2> { }

무슨 말인지 알겠어?

를 조금 위해서 는 이 이나마 요구하려고 합니다.Static<TClass, ...> TClass 이것은 가 없습니다.InstanceType<TClass>멤버가 . , 에는 인스턴스 멤버가 없습니다★★★★★★★★★★★★★★★★★,Cat2를 누릅니다

FakeCat 실장하다Cat2. -어렵지 않다.{ }.

데모

놀이터 링크

Kamil Szot과 같은 솔루션을 구현했는데, 바람직하지 않은 효과가 있습니다.댓글로 올릴 만한 평판이 없어서 혹시 누군가 그 해결책을 시도해서 읽을까 봐 여기에 올립니다.

해결책은 다음과 같습니다.

interface MyInterface {
    Name: string;
}

const MyClass = class {
    static Name: string;
};

, 래, 클, 클, 클, ,, ,, ,, ,, however, however, however, however, however, however, however, however, however, however, however, however, however, however, however, however, however however,MyClass'이것'은 다음과 같습니다.

const myInstance: MyClass;

myInstance이 나다any에디터에는 다음 오류가 표시됩니다.

'MyClass' refers to a value, but is being used as a type here. Did you mean 'typeof MyClass'?ts(2749)

수업의 정적 부분을 위한 인터페이스로 얻으려고 했던 것보다 더 중요한 타이핑이 없어졌습니다.

발은 데코레이터를 사용하여 이 함정을 피한다.

스태틱 컨스트럭터를 추가하는 사용 사례에 있어서, 이 솔루션은 훌륭하게 기능하고 있습니다.테스트를 해봤는데 모든 테스트를 통과했어요.혹시 버그가 있는 케이스가 발견되면 알려주세요.

인터페이스와 스태틱인터페이스를 받아들이는 범용 타입을 만들었습니다.

그것은 구체적이고 추상적인 수업에서 효과가 있다.

모든 오류가 인터페이스 자체가 아닌 인터페이스를 구현하는 클래스에 전파되도록 조건부 유형을 사용하여 설계했습니다.

참고: 오류 전파를 통해 vscode를 신속하게 수정할 수 있습니다(모든 방법 구현).유일한 단점은 static 키워드를 직접 적용해야 한다는 것입니다.이 오류에 대한 빠른 수정이 없기 때문입니다.

인터페이스:

type Class<T = any> = new (...args: any[]) => T;
type AbstractClass<T = any> = abstract new (...args: any[]) => T;

type Interface<C extends Class<InstanceType<C>> | AbstractClass<InstanceType<C>>, SI, I = {}> = 
    C extends Class<InstanceType<C>> 
    // ConcreteClass
    ? InstanceType<C> extends I 
        ? C extends (SI & Class<InstanceType<C>>)
            ? (InstanceType<C> & I)
            : (SI & Class<InstanceType<C>>) // Indicate StaticInterface Error
        : I // Indicate Interface Error
    // AbstractClass
    : InstanceType<C> extends I 
        ? C extends (SI & AbstractClass<InstanceType<C>>)
            ? (InstanceType<C> & I)
            : (SI & AbstractClass<InstanceType<C>>) // Indicate StaticInterface Error
        : I // Indicate Interface Error

사용방법:

interface MyInterface {
    instanceMethod(): number;
}

interface MyStaticInterface {
    staticMethod(): number;
}
 
class MyClass implements Interface<typeof MyClass, MyStaticInterface, MyInterface> {
    static staticMethod(): number {
        return 50;
    }

    instanceMethod(): number {
        return 100;
    }

    static otherStatic() {
        return "HELLO"
    }

    otherInstance() {
        return "GOODBYE"
    }
}

abstract class MyClass1 implements Interface<typeof MyClass1, MyStaticInterface, MyInterface> {
    static staticMethod(): number {
        return 50;
    }


    instanceMethod(): number {
        return 20;
    }

    static otherStatic() {
        return "HELLO"
    }

    otherInstance() {
        return "GOODBYE"
    }

    abstract abstractMethod() : number;

}

간단한 예

interface Person {
  name: string;
  age: number;
}

abstract class Trackable {
  static TrackInstances: number;
}

class Pablo extends Trackable implements Person {
  constructor(public name: string, public age: number) { Pablo.TrackInstances+=1; }
}
console.log(Pablo.TrackInstances);

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