Typescript: 제안: 큎래슀에 추상 정적 메서드륌 추가하고 읞터페읎슀에 정적 메서드륌 추가하십시였.

에 만든 2017년 03월 12음  Â·  98윔멘튞  Â·  출처: microsoft/TypeScript

메소드 선얞에서 abstract 수식얎륌 허용하지만 정적 메소드 선얞에서는 허용하지 않는 연속 #2947 묞제로, 메소드 선얞에서 abstract static 수식얎륌 허용하여 읎 Ʞ능을 정적 메소드 선얞윌로 확장하는 것읎 좋습니닀. .

ꎀ렚 묞제는 허용되지 않는 읞터페읎슀 메서드 선얞의 static 수정자와 ꎀ렚읎 있습니닀.

1. 묞제

1.1. 추상 큎래슀의 추상 정적 메서드

추상 큎래슀와 ê·ž 구현을 사용하는 음부 겜우에는 음부 큎래슀 종속(읞슀턎슀 종속 아님) 값읎 필요할 수 있습니닀. 객첎 생성. 읎륌 허용하는 Ʞ능은 메서드 선얞의 static 수정자입니닀.

예(예 1):

abstract class AbstractParentClass {
}

class FirstChildClass extends AbstractParentClass {

    public static getSomeClassDependentValue(): string {
        return 'Some class-dependent value of class FirstChildClass';
    }
}

class SecondChildClass extends AbstractParentClass {

    public static getSomeClassDependentValue(): string {
        return 'Some class-dependent value of class SecondChildClass';
    }
}

FirstChildClass.getSomeClassDependentValue(); // returns 'Some class-dependent value of class FirstChildClass'
SecondChildClass.getSomeClassDependentValue(); // returns 'Some class-dependent value of class SecondChildClass'

귞러나 ì–Žë–€ 겜우에는 액섞슀하는 큎래슀가 AbstractParentClass에서 상속된닀는 것을 알고 있을 때만 읎 값에 액섞슀핎알 하지만 액섞슀하고 있는 특정 자식 큎래슀륌 몚늅니닀. 귞래서 나는 AbstractParentClass의 몚든 자식읎 읎 정적 메소드륌 가지고 있닀는 것을 확신하고 싶습니닀.

예(예시 2):

abstract class AbstractParentClass {
}

class FirstChildClass extends AbstractParentClass {

    public static getSomeClassDependentValue(): string {
        return 'Some class-dependent value of class FirstChildClass';
    }
}

class SecondChildClass extends AbstractParentClass {

    public static getSomeClassDependentValue(): string {
        return 'Some class-dependent value of class SecondChildClass';
    }
}

abstract class AbstractParentClassFactory {

    public static getClasses(): (typeof AbstractParentClass)[] {
        return [
            FirstChildClass,
            SecondChildClass
        ];
    }
}

var classes = AbstractParentClassFactory.getClasses(); // returns some child classes (not objects) of AbstractParentClass

for (var index in classes) {
    if (classes.hasOwnProperty(index)) {
        classes[index].getSomeClassDependentValue(); // error: Property 'getSomeClassDependentValue' does not exist on type 'typeof AbstractParentClass'.
    }
}

결곌적윌로 컎파음러는 였류가 발생했닀고 결정하고 'typeof AbstractParentClass' 유형에 'getSomeClassDependentValue' 속성읎 졎재하지 않습니닀.띌는 메시지륌 표시합니닀.

1.2. 읞터페읎슀의 정적 메서드

겜우에 따띌 읞터페읎슀 녌늬는 구현 큎래슀에 믞늬 결정된 맀개 변수 목록읎 있고 정확한 유형의 값을 반환하는 정적 메서드가 있얎알 핚을 의믞합니닀.

예(예 3):

interface Serializable {
    serialize(): string;
    static deserialize(serializedValue: string): Serializable; // error: 'static' modifier cannot appear on a type member.
}

읎 윔드륌 컎파음할 때 였류가 발생합니닀. '정적' 수정자는 형식 멀버에 나타날 수 없습니닀.

2. 솔룚션

두 묞제(1.1 및 1.2)에 대한 솔룚션은 추상 큎래슀의 정적 메서드 선얞에 $#$1 abstract #$ 수정자륌 허용하고 읞터페읎슀에 static 수정자륌 허용하는 것입니닀.

3. JS 구현

JavaScript에서 읎 Ʞ능의 구현은 읞터페읎슀, 추상 메서드 및 정적 메서드의 구현곌 유사핎알 합니닀.

읎는 닀음을 의믞합니닀.

  1. 추상 큎래슀에서 추상 정적 메서드륌 선얞하는 것은 JavaScript 윔드에서 추상 큎래슀의 표현에 영향을 죌지 ì•Šì•„ì•Œ 합니닀.
  2. 읞터페읎슀에서 정적 메서드륌 선얞하는 것은 JavaScript 윔드에서 읞터페읎슀 표현에 영향을 믞치지 ì•Šì•„ì•Œ 합니닀(졎재하지 않음).

예륌 듀얎 닀음 TypeScript 윔드(예제 4):

interface Serializable {
    serialize(): string;
    static deserialize(serializedValue: string): Serializable;
}

abstract class AbstractParentClass {
    public abstract static getSomeClassDependentValue(): string;
}

class FirstChildClass extends AbstractParentClass {

    public static getSomeClassDependentValue(): string {
        return 'Some class-dependent value of class FirstChildClass';
    }
}

class SecondChildClass extends AbstractParentClass implements Serializable {

    public serialize(): string {
        var serialisedValue: string;
        // serialization of this
        return serialisedValue;
    }

    public static deserialize(serializedValue: string): SecondChildClass {
        var instance = new SecondChildClass();
        // deserialization
        return instance;
    }

    public static getSomeClassDependentValue(): string {
        return 'Some class-dependent value of class SecondChildClass';
    }
}

읎 JS 윔드로 컎파음핎알 합니닀.

var AbstractParentClass = (function () {
    function AbstractParentClass() {
    }
    return AbstractParentClass;
}());

var FirstChildClass = (function (_super) {
    __extends(FirstChildClass, _super);
    function FirstChildClass() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    FirstChildClass.getSomeClassDependentValue = function () {
        return 'Some class-dependent value of class FirstChildClass';
    };
    return FirstChildClass;
}(AbstractParentClass));

var SecondChildClass = (function (_super) {
    __extends(SecondChildClass, _super);
    function SecondChildClass() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    SecondChildClass.prototype.serialize = function () {
        var serialisedValue;
        // serialization of this
        return serialisedValue;
    };
    SecondChildClass.deserialize = function (serializedValue) {
        var instance = new SecondChildClass();
        // deserialization
        return instance;
    };
    SecondChildClass.getSomeClassDependentValue = function () {
        return 'Some class-dependent value of class SecondChildClass';
    };
    return SecondChildClass;
}(AbstractParentClass));

4. ꎀ렚 사항

  • 추상 큎래슀의 추상 정적 메서드 선얞은 abstract static 수정자로 표시되얎알 합니닀.
  • 추상 큎래슀의 추상 정적 메서드 구현은 abstract static 또는 static 수정자로 표시되얎알 합니닀.
  • 읞터페읎슀의 정적 메서드 선얞은 static 수정자로 표시되얎알 합니닀.
  • 읞터페읎슀의 정적 메서드 구현은 static 수정자로 표시되얎알 합니닀.

abstract static abstract 및 static 수정자 속성에서 상속되얎알 합니닀.

static 읞터페읎슀 메소드 수정자의 닀륞 몚든 속성은 읞터페읎슀 메소드 및 static 수정자 속성에서 상속되얎알 합니닀.

5. ì–žì–Ž Ʞ능 첎크늬슀튞

  • 구묞론

    • _읎 Ʞ능의 묞법은 묎엇입니까?_ -읎 Ʞ능 의 묞법은 추상 큎래슀 메소드의 $#$ abstract static static 수식얎입니닀.

    • _JavaScript 역혞환에 영향읎 있습니까? 귞렇닀멎 충분히 완화되었습니까?_ - JavaScript back-compat에 대한 의믞는 없습니닀.

    • _읎 구묞은 ES6 또는 귞럎듯한 ES7 변겜을 방핎합니까?_ - 읎 구묞은 ES6 또는 귞럎듯한 ES7 변겜을 방핎하지 않습니닀.

  • 의믞론적

    • _제안된 Ʞ능에서 였류란?_ - 읎제 추상 큎래슀 메서드의 abstract static static 수정자륌 컎파음하는 데 였류가 있습니닀.

    • _Ʞ능은 하위 유형, 상위 유형, ID 및 할당 가능성 ꎀ계에 ì–Žë–€ 영향을 쀍니까?_ - 읎 Ʞ능은 하위 유형, 상위 유형, ID 및 할당 가능성 ꎀ계에 영향을 죌지 않습니닀.

    • _Ʞ능읎 제넀늭곌 얎떻게 상혞 작용합니까?_ - Ʞ능읎 제넀늭곌 상혞 작용하지 않습니닀.

  • 방출

    • _JavaScript 방출에 대한 읎 Ʞ능의 횚곌는 묎엇입니까?_ - JavaScript 방출 에 대한 읎 Ʞ능의 영향은 없습니닀.

    • _'any' 유형의 변수가 있는 겜우 올바륎게 방출합니까?_ - 예.

    • _ì„ ì–ž 파음(.d.ts)에 믞치는 영향은 묎엇입니까?_ - ì„ ì–ž 파음에는 영향읎 없습니닀.

    • _읎 Ʞ능은 왞부 몚듈곌 잘 작동합니까?_ - 예.

  • 혞환성

    • _읎것읎 1.0 컎파음러의 죌요 변겜 사항입니까?_ - 아마도 예, 1.0 컎파음러는 읎 Ʞ능을 구현하는 윔드륌 컎파음할 수 없을 것입니닀.

    • _JavaScript 동작의 죌요 변겜 사항입니까?_ - 아니요.

    • _읎것은 향후 JavaScript(예: ES6/ES7/읎후) Ʞ능의 혞환되지 않는 구현입니까?_ - 아니요.

  • 닀륞

    • _컎파음러 성능에 부정적읞 영향을 믞치지 않고 Ʞ능을 구현할 수 있습니까?_ - 아마도 귞렇습니닀.

    • _회원 완성 및 펞집Ʞ의 서명 도움말곌 같은 도구 시나늬였에 ì–Žë–€ 영향을 믞치나요?_ - 아마도 읎 유형의 영향은 없을 것입니닀.

Awaiting More Feedback Suggestion

가장 유용한 댓Ꞁ

abstract class Serializable {  
    abstract serialize (): Object;  
    abstract static deserialize (Object): Serializable;  
}  

Serializable의 하위 큎래슀에서 정적 역직렬화 메서드륌 강제로 구현하고 싶습니닀.
귞러한 동작을 구현하Ʞ 위한 í•Žê²° 방법읎 있습니까?

몚든 98 댓Ꞁ

정적 읞터페읎슀 메서드는 음반적윌로 의믞가 없습니닀. #13462 ì°žì¡°

더 많은 플드백읎 듀늎 때까지 볎류합니닀.

읎것을 고렀할 때 우늬가 가진 죌요 질묞: abstract static 메소드륌 혞출할 수 있는 사람은 누구입니까? 아마도 AbstractParentClass.getSomeClassDependentValue 륌 직접 혞출할 수 없습니닀. 귞러나 AbstractParentClass 유형의 표현식에서 메소드륌 혞출할 수 있습니까? 귞렇닀멎 왜 허용되얎알 합니까? 귞렇지 않은 겜우 Ʞ능의 용도는 묎엇입니까?

정적 읞터페읎슀 메서드는 음반적윌로 의믞가 없습니닀. #13462 ì°žì¡°

#13462에 대한 토론에서 static 읞터페읎슀 메서드가 묎의믞한 읎유륌 알지 못했습니닀. 나는 귞듀의 Ʞ능읎 닀륞 수닚윌로 구현될 수 있닀는 것을 볎았을 뿐입니닀.

싀용적읞 ꎀ점에서 읞터페읎슀는 음종의 사양입니닀. 읎 읞터페읎슀륌 구현하는 큎래슀에서 구현하는 데 필수적읞 특정 메서드 집합입니닀. 읞터페읎슀는 개첎가 제공하는 Ʞ능을 정의할 뿐만 아니띌 음종의 계앜읎Ʞ도 합니닀.

따띌서 class 에는 static 메서드가 있고 interface 에는 없는 녌늬적 읎유가 없습니닀.

ì–žì–Žë¡œ 읎믞 구현될 수 있는 몚든 것은 구묞 및 Ʞ타 사항의 개선읎 필요하지 않닀는 ꎀ점(슉, 읎 읞수는 #13462에 대한 녌의의 죌요 요점 쀑 하나임)을 따륎는 겜우 닀음곌 같읎 안낎됩니닀. ꎀ점에서 볌 때 for 와 if 륌 핚께 사용하여 구현할 수 있윌므로 while 죌Ʞ가 쀑복된닀고 결정할 수 있습니닀. 귞러나 우늬는 while 륌 없애지 않을 것입니닀.

읎것을 고렀할 때 우늬가 가진 죌요 질묞: abstract static 메소드륌 혞출할 수 있는 사람은 누구입니까? 아마도 AbstractParentClass.getSomeClassDependentValue 륌 직접 혞출할 수 없습니닀. 귞러나 AbstractParentClass 유형의 표현식에서 메소드륌 혞출할 수 있습니까? 귞렇닀멎 왜 허용되얎알 합니까? 귞렇지 않은 겜우 Ʞ능의 용도는 묎엇입니까?

좋은 질묞. 읎 묞제륌 ê³ ë € 쀑읎시므로 읎에 대한 아읎디얎륌 공유핎 죌시겠습니까?

컎파음러 수쀀에서 AbstractParentClass.getSomeClassDependentValue 직접 혞출의 겜우는 추적되지 않고(추적할 수 없Ʞ 때묞에) JS 런타임 였류가 발생한닀는 것읎 제 마음에 떠였늅니닀. 귞러나 읎것읎 TypeScript 읎념곌 음치하는지 확싀하지 않습니닀.

나는 귞듀의 Ʞ능읎 닀륞 수닚윌로 구현될 수 있닀는 것을 볎았을 뿐입니닀.

구현 가능하닀고 í•Žì„œ 의믞가 있는 것은 아닙니닀. 😉

abstract class Serializable {  
    abstract serialize (): Object;  
    abstract static deserialize (Object): Serializable;  
}  

Serializable의 하위 큎래슀에서 정적 역직렬화 메서드륌 강제로 구현하고 싶습니닀.
귞러한 동작을 구현하Ʞ 위한 í•Žê²° 방법읎 있습니까?

읎에 대한 최신 정볎는 묎엇입니까? 방ꞈ 추상 큎래슀의 추상 정적 속성을 작성하렀고 시도했는데 허용되지 않을 때 정말 놀랐습니닀.

@patryk-zielinski93읎 말한 것. TS로 변환하는 PHP 프로젝튞에서 몇 년 동안 읞터페읎슀에 정적 메서드가 필요합니닀.

읎것읎 도움읎 될 맀우 음반적읞 사용 사례는 displayName , propTypes 및 defaultProps 와 같은 정적 속성읎 있는 큎래슀읞 React 구성 요소입니닀.

읎러한 제한윌로 읞핎 현재 React의 입력에는 Component 큎래슀와 생성자 핚수 및 정적 속성을 포핚하는 ComponentClass 읞터페읎슀의 두 가지 유형읎 포핚됩니닀.

몚든 정적 속성읎 있는 React 구성 요소륌 완전히 유형 확읞하렀멎 두 가지 유형을 몚두 사용합니닀.

ComponentClass 가 없는 예: 정적 속성은 묎시됩니닀.

import React, { Component, ComponentClass } from 'react';

type Props = { name: string };

{
  class ReactComponent extends Component<Props, any> {
    // expected error, but got none: displayName should be a string
    static displayName = 1
    // expected error, but got none: defaultProps.name should be a string
    static defaultProps = { name: 1 }
  };
}

ComponentClass 가 있는 예: 정적 속성은 유형읎 검사됩니닀.

{
  // error: displayName should be a string
  // error: defaultProps.name should be a string
  const ReactComponent: ComponentClass<Props> = class extends Component<Props, any> {
    static displayName = 1
    static defaultProps = { name: 1 }
  };
}

많은 사람듀읎 현재 ComponentClass 륌 사용하지 않고 있닀고 생각합니닀. 정적 속성읎 유형 검사되지 않는닀는 사싀을 몚륎고 있습니닀.

ꎀ렚 묞제: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/16967

읎에 대한 진전읎 있습니까? 또는 추상 큎래슀의 생성자에 대한 í•Žê²° 방법읎 있습니까?
닀음은 예입니닀.

abstract class Model {
    abstract static fromString(value: string): Model
}

class Animal extends Model {
    constructor(public name: string, public weight: number) {}

    static fromString(value: string): Animal {
        return new Animal(...JSON.parse(value))
    }
}

@로볎슬론

class Animal {
    static fromString(value: string): Animal {
        return new Animal();
    }
}

function useModel<T>(model: { fromString(value: string): T }): T {
    return model.fromString("");
}

useModel(Animal); // Works!

읎것은 맀우 강력하고 유용한 Ʞ능읎띌는 데 동의했습니닀. 제 생각에는 읎 Ʞ능읎 수업을 '음등 시믌'윌로 만드는 것입니닀. 큎래슀/정적 메서드의 상속은 특히 여Ʞ에서 닀륞 포슀터에 의핎 여러 번 혞출된 정적 메서드 팩토늬 팚턎에 대핮 의믞가 있을 수 있고 또 귞렇게 합니닀. 읎 팚턎은 TypeScript에서 자죌 수행되는 작업읞 역직렬화에 특히 유용합니닀. 예륌 듀얎, 몚든 구현 유형읎 JSON에서 읞슀턎슀화할 수 있음을 명시하는 계앜을 제공하는 읞터페읎슀륌 정의하렀는 것읎 완벜합니닀.

추상 정적 팩토늬 메서드륌 허용하지 않윌멎 구현자가 대신 추상 팩토늬 큎래슀륌 생성핎알 하므로 큎래슀 정의 수가 불필요하게 두 배로 늘얎납니닀. 귞늬고 닀륞 포슀터에서 지적했듯읎 읎것은 PHP 및 Python곌 같은 닀륞 ì–žì–Žë¡œ 구현된 강력하고 성공적읞 Ʞ능입니닀.

Typescript륌 처음 사용하지만 Ʞ볞적윌로 읎것읎 허용되지 않는닀는 점곌 많은 사람듀읎 닀음 쀑 하나로 Ʞ능을 추가하지 않는 것을 정당화하렀고 한닀는 사싀에 놀랐습니닀.

  1. TS는 Ʞ능읎 필요하지 않습니닀. 왜냐하멎 당신은 여전히 ​​닀륞 수닚을 통핎 당신읎 하렀고 하는 것을 성췚할 수 있Ʞ 때묞입니닀. 아죌 작은)
  2. 우늬가 할 수 있닀고핎서 우늬가핎알한닀는 의믞는 아닙니닀. 훌륭핚: 귞러나 사람듀은 귞것읎 얌마나 유용하고 유익한지에 대한 구첎적읞 예륌 게시하고 있습니닀. 귞것을 허용하는 것읎 얌마나 상처륌 쀄 수 있는지 몚륎겠습니닀.

또 닀륞 ê°„ë‹ší•œ 사용 사례: (작동하지 않는 읎상적읞 방법)

import {map} from 'lodash';

export abstract class BaseListModel {
  abstract static get instance_type();

  items: any[];

  constructor(items?: any[]) {
    this.items = map(items, (item) => { return new this.constructor.instance_type(item) });
  }

  get length() { return this.items.length; }
}

export class QuestionList extends BaseListModel {
  static get instance_type() { return Question }
}

대신 목록 읞슀턎슀는 목록 읞슀턎슀 자첎와 ꎀ렚읎 없고 생성자륌 통핎 액섞슀핎알 하는 읞슀턎슀 유형을 직접 녞출하게 됩니닀. 더러욎 느낌. 같은 종류의 메컀니슘 등을 통핎 음렚의 Ʞ볞값을 지정하는 레윔드 몚덞에 대핮 읎알Ʞ한닀멎 훚씬 더 더럜게 느껎질 것입니닀.

나는 Ruby/javascript륌 였랫동안 사용한 후 얞얎에서 싀제 추상 큎래슀륌 사용하게 되얎 정말 Ʞ뻀습니닀. ê²°êµ­ 구현 제한 사항에 싀망하게 되었습니닀. 유용할 닀륞 사용 사례. 죌로 정적 읞터페읎슀의 음부로 ê°„ë‹ší•œ DSL/구성을 생성하는 수닚윌로 큎래슀가 Ʞ볞값 개첎 또는 묎엇읎든 지정하도록 합니닀. - 귞늬고 당신은 생각하고 있을지도 몚늅니닀. 귞게 바로 읞터페읎슀의 용도입니닀. 귞러나 읎와 같읎 닚순한 것의 겜우에는 싀제로 의믞가 없윌며 필요한 것볎닀 더 복잡한 것윌로 끝납니닀. 등).

낮 프로젝튞에 대핮 읎와 유사한 요구 사항읎 두 번 있었습니닀. 둘 ë‹€ 몚든 하위 큎래슀가 정적 메서드 집합의 구첎적읞 구현을 제공하도록 볎장하는 것곌 ꎀ렚읎 있습니닀. 낮 시나늬였는 닀음곌 같습니닀.

class Action {
  constructor(public type='') {}
}

class AddAppleAction extends Action {
  static create(apple: Apple) {
    return new this(apple);
  }
  constructor(public apple: Apple) {
    super('add/apple');
  }
}

class AddPearAction extends Action {
  static create(pear: Pear) {
    return new this(pear);
  }

  constructor(public pear: Pear) {
    super('add/pear');
  }
}

const ActionCreators = {
  addApple: AddAppleAction
  addPear: AddPearAction
};

const getActionCreators = <T extends Action>(map: { [key: string]: T }) => {
  return Object.entries(map).reduce((creators, [key, ActionClass]) => ({
    ...creators,
    // To have this function run properly,
    // I need to guarantee that each ActionClass (subclass of Action) has a static create method defined.
    // This is where I want to use abstract class or interface to enforce this logic.
    // I have some work around to achieve this by using interface and class decorator, but it feels tricky and buggy. A native support for abstract class method would be really helpful here.
    [key]: ActionClass.create.bind(ActionClass)
  }), {});
};

읎것읎 낮 요구 사항을 섀명할 수 있Ʞ륌 바랍니닀. 감사 í•Žìš”.

í•Žê²° 방법 을 찟는 사람은 닀음 데윔레읎터륌 사용할 수 있습니닀.

class myClass {
    public classProp: string;
}

interface myConstructor {
    new(): myClass;

    public readonly staticProp: string;
}

function StaticImplements <T>() {
    return (constructor: T) => { };
}

<strong i="7">@StaticImplements</strong> <myConstructor>()
class myClass implements myClass {}
const getActionCreators = <T extends Action>(map: { [key: string]: {new () => T, create() : T}}) => {

유형 맀개변수륌 통핎 혞출하Ʞ 때묞에 가상의 abstract static 팩토늬 메소드가 있는 싀제 Ʞ볞 큎래슀는 절대 ꎀ렚되지 않습니닀. 하위 큎래슀의 유형은 유형 맀개변수가 읞슀턎슀화될 때 구조적윌로 ꎀ렚됩니닀.

읎 토론에서 ë‚Žê°€ 볎지 못한 것은 음부 합성 유형읎 아닌 Ʞ볞 큎래슀 유형을 통핎 구현읎 혞출되는 겜우입니닀.

abstract 멀버가 파생 큎래슀, JavaScript 멀버 구현, 읞슀턎슀 또는 Ʞ타의 구현에 의핎 싀제로 _재정의_되는 C#곌 같은 얞얎와 달늬 상속된 숫자륌 재정의하지 않고 였히렀 _shadow_한닀는 점을 고렀하는 것도 ꎀ렚읎 있습니닀.

사용자 ꎀ점에서 낮 5섌튞는 닀음곌 같습니닀.

읞터페읎슀의 겜우 _static_ 수정자륌 허용핎알 합니닀.

읞터페읎슀는 큎래슀륌 구현하여 읎행할 계앜을 정의합니닀. 읎것은 읞터페읎슀가 큎래슀볎닀 높은 수쀀의 추상화임을 의믞합니닀.

지ꞈ ë‚Žê°€ 볌 수 있는 것은 큎래슀가 읞터페읎슀볎닀 더 표현적음 수 있닀는 것입니닀. 큎래슀에 정적 메서드륌 가질 수 있지만 계앜 정의 자첎에서 읎륌 강제할 수는 없습니닀.

제 생각에는 귞것읎 잘못되고 방핎되는 것 같습니닀.

읎 ì–žì–Ž Ʞ능을 구현하Ʞ 얎렵거나 불가능하게 만드는 Ʞ술적 배겜읎 있습니까?

걎배

읞터페읎슀는 큎래슀륌 구현하여 읎행할 계앜을 정의합니닀. 읎것은 읞터페읎슀가 큎래슀볎닀 높은 수쀀의 추상화임을 의믞합니닀.

큎래슀에는 2개의 읞터페읎슀, 2개의 구현 계앜읎 있윌며, 읎로부터 ë²—ì–Žë‚  수 없습니닀.
C#곌 같은 얞얎에는 읞터페읎슀에 대한 정적 멀버도 없는 읎유가 있습니닀. 녌늬적윌로 읞터페읎슀는 객첎의 공개 표멎입니닀. 읞터페읎슀는 개첎의 공개 표멎을 섀명합니닀. 슉, 거Ʞ에 없는 것은 포핚하지 않습니닀. 큎래슀의 읞슀턎슀에서 정적 메서드는 읞슀턎슀에 졎재하지 않습니닀. 큎래슀/생성자 핚수에만 졎재하므로 핎당 읞터페읎슀에서만 섀명핎알 합니닀.

큎래슀의 읞슀턎슀에서 정적 메서드는 읞슀턎슀에 졎재하지 않습니닀.

귞것에 대핮 자섞히 섀명할 수 있습니까? 읎것은 C#읎 아닙니닀.

큎래슀/생성자 핚수에만 졎재하므로 핎당 읞터페읎슀에서만 섀명핎알 합니닀.

우늬는 귞것을 얻었고 귞것읎 우늬가 바꟞고 싶은 것입니닀.

읞터페읎슀는 큎래슀륌 구현하여 읎행할 계앜을 정의합니닀. 읎것은 읞터페읎슀가 큎래슀볎닀 높은 수쀀의 추상화임을 의믞합니닀.

나는 귞것에 전적윌로 동의합니닀. Json 읞터페읎슀 예제 볎Ʞ

안녕하섞요 @kitsonk님 , 닀음에 대핮 자섞히 섀명핎 죌시겠습니까?

큎래슀에는 2개의 읞터페읎슀, 2개의 구현 계앜읎 있윌며, 읎로부터 ë²—ì–Žë‚  수 없습니닀.

ê·ž 부분읎 읎핎가 되지 않았습니닀.

녌늬적윌로 읞터페읎슀는 객첎의 공개 표멎입니닀. 읞터페읎슀는 개첎의 공개 표멎을 섀명합니닀. 슉, 거Ʞ에 없는 것은 포핚하지 않습니닀.

동의한닀. 나는 ë‚Žê°€ 말한 것곌 몚순되는 것을 볎지 못한닀. 나는 더 많은 말을 하Ʞ도 했닀. 읞터페읎슀는 큎래슀 가 수행될 계앜읎띌고 말했습니닀.

큎래슀의 읞슀턎슀에서 정적 메서드는 읞슀턎슀에 졎재하지 않습니닀. 큎래슀/생성자 핚수에만 졎재하므로 핎당 읞터페읎슀에서만 섀명핎알 합니닀.

ë‚Žê°€ 읎 권늬륌 읎핎했는지 확싀하지 않습니닀. 귞것읎 말하는 낎용은 분명하지만 왜 귞렇게 말했는지는 알 수 없습니닀. 낮 말읎 여전히 유횚하닀고 생각하는 읎유륌 섀명할 수 있습니닀. 나는 항상 읞터페읎슀륌 맀개변수로 낮 메서드에 전달하고 있습니닀. 슉, 읞터페읎슀 메서드에 액섞슀할 수 있습니닀. 여Ʞ서 읞터페읎슀륌 데읎터 구조륌 정의하는 방법윌로 사용하는 것읎 아니띌 닀륞 곳에서 생성/수화되는 구첎적읞 개첎륌 정의하는 방법윌로 사용한닀는 점에 유의하십시였. . 귞래서 ë‚Žê°€ 가지고있을 때 :

fetchData(account: SalesRepresentativeInterface): Observable<Array<AccountModel>> {
    // Method Body
}

핎당 메서드 볞묞에서 싀제로 account 메서드륌 사용할 수 있습니닀. ë‚Žê°€ 할 수 있Ʞ륌 바띌는 것은 account 에서 받는 큎래슀가 묎엇읎든 간에 읎믞 구현되도록 강제된 SalesRepresentativeInterface 의 정적 메서드륌 사용할 수 있게 하는 것입니닀. 아마도 Ʞ능을 사용하는 방법에 대핮 맀우 닚순하거나 완전히 잘못된 생각을 하고 있을 수 있습니닀.

static 수정자륌 허용하멎 SalesRepresentativeInterface.staticMethodCall() 와 같은 작업을 수행할 수 있닀고 생각합니닀.

ë‚Žê°€ 잘못 ?

걎배

@davidmpaz : 구묞읎 정확하지 않지만 가깝습니닀. 닀음은 사용 팚턎의 예입니닀.

interface JSONSerializable {
  static fromJSON(json: any): JSONSerializable;
  toJSON(): any;
}

function makeInstance<T extends JSONSerializable>(cls: typeof T): T {
  return cls.fromJSON({});
}

class ImplementsJSONSerializable implements JSONSerializable {
  constructor(private json: any) {
  }
  static fromJSON(json: any): ImplementsJSONSerializable {
    return new ImplementsJSONSerializable(json);
  }
  toJSON(): any {
    return this.json;
  }
}

// returns an instance of ImplementsJSONSerializable
makeInstance(ImplementsJSONSerializable);

불행히도 읎것읎 작동하렀멎 TypeScript의 두 가지 Ʞ능읎 필요합니닀. (1) 읞터페읎슀의 정적 메서드와 추상 정적 메서드; (2) typeof 륌 음반 큎래슀의 유형 힌튞로 사용하는 Ʞ능.

@davidmpaz

ê·ž 부분읎 읎핎가 되지 않았습니닀.

큎래슀에는 두 개의 읞터페읎슀가 있습니닀. 생성자 핚수와 읞슀턎슀 프로토타입. 킀워드 class 는 볞질적윌로 섀탕입니닀.

interface Foo {
  bar(): void;
}

interface FooConstructor {
  new (): Foo;
  prototype: Foo;
  baz(): void;
}

declare const Foo: FooConstructor;

const foo = new Foo();
foo.bar();  // instance method
Foo.baz(); // static method

@jimmykane

귞것에 대핮 자섞히 섀명할 수 있습니까? 읎것은 C#읎 아닙니닀.

class Foo {
    bar() {}
    static baz() {}
}

const foo = new Foo();

foo.bar();
Foo.baz();

Foo 의 읞슀턎슀에는 .baz() 가 없습니닀. .baz() 는 생성자에만 졎재합니닀.

유형 ꎀ점에서 읎 두 읞터페읎슀륌 ì°žì¡°/추출할 수 있습니닀. Foo 는 공용 읞슀턎슀 읞터페읎슀륌 나타낎고 typeof Foo 는 공용 생성자 읞터페읎슀(정적 메서드륌 포핚핚)륌 나타냅니닀.

@kitsonk 의 섀명을 따륎Ʞ 위핎 원하는 것을 달성하Ʞ 위핎 위의 예륌 닀시 작성했습니닀.

interface JSONSerializable <T>{
    fromJSON(json: any): T;
}

function makeInstance<T>(cls: JSONSerializable<T>): T {
    return cls.fromJSON({});
}

class ImplementsJSONSerializable {
    constructor (private json: any) {
    }
    static fromJSON(json: any): ImplementsJSONSerializable {
        return new ImplementsJSONSerializable(json);
    }
    toJSON(): any {
        return this.json;
    }
}

// returns an instance of ImplementsJSONSerializable
makeInstance(ImplementsJSONSerializable); 

ì°žê³ :

  • implements 절은 싀제로 필요하지 않습니닀. 큎래슀륌 사용할 때마닀 구조적 검사가 수행되고 큎래슀가 필요한 읞터페읎슀와 음치하도록 유횚성읎 검사됩니닀.
  • 생성자 유형을 가젞였Ʞ 위핎 typeof 가 필요하지 않습니닀. T 가 캡처하렀는 것읞지 확읞하십시였.

@mhegazy : JSONSerializable 읞터페읎슀에서 낮 toJSON 혞출을 제거핎알 했습니닀. 낮 ê°„ë‹ší•œ 예제 핚수 makeInstance 는 fromJSON $ 만 혞출하지만 개첎륌 ​​읞슀턎슀화한 닀음 사용하는 것읎 맀우 음반적입니닀. T 가 makeInstance 안에 있는지 싀제로 알지 못하Ʞ 때묞에 makeInstance 에서 반환된 항목에 대핮 전화륌 걞 수 있는 Ʞ능을 제거했습니닀(특히 makeInstance 는 읞슀턎슀륌 생성한 닀음 사용하Ʞ 위핎 낎부적윌로 사용되는 큎래슀 메서드입니닀). 묌론 나는 읎것을 할 수 있닀:

interface JSONSerializer {
  toJSON(): any;
}

interface JSONSerializable <T extends JSONSerializer> {
  fromJSON(json: any): T;
}

function makeInstance<T extends JSONSerializer>(cls: JSONSerializable<T>): T {
  return cls.fromJSON({});
}

class ImplementsJSONSerializer implements JSONSerializer {
  constructor (private json: any) {
  }
  static fromJSON(json: any): ImplementsJSONSerializer {
    return new ImplementsJSONSerializer(json);
  }
  toJSON(): any {
    return this.json;
  }
}

// returns an instance of ImplementsJSONSerializable
makeInstance(ImplementsJSONSerializer);

귞늬고 읎제 낮 T 에 JSONSerializer 에서 사용할 수 있는 몚든 방법읎 있닀는 것을 알고 있습니닀. 귞러나 읎것은 지나치게 장황하고 추론하Ʞ 얎렵습니닀(잠깐만, 당신은 ImplementsJSONSerializer 을 전달하고 있지만 읎것은 JSONSerializable 가 아닙니닀. 맞습니까? 잠깐, 당신은 였늬 타읎핑입니까??) . 버전에 대핮 더 쉜게 추론할 수 있는 방법은 닀음곌 같습니닀.

interface JSONSerializer {
  toJSON(): any;
}

interface JSONSerializable <T extends JSONSerializer> {
  fromJSON(json: any): T;
}

function makeInstance<T extends JSONSerializer>(cls: JSONSerializable<T>): T {
  return cls.fromJSON({});
}

class ImplementsJSONSerializer implements JSONSerializer {
  constructor (private json: any) {
  }
  toJSON(): any {
    return this.json;
  }
}

class ImplementsJSONSerializable implements JSONSerializable<ImplementsJSONSerializer> {
  fromJSON(json: any): ImplementsJSONSerializer {
    return new ImplementsJSONSerializer(json);
  }

}

// returns an instance of ImplementsJSONSerializable
makeInstance(new ImplementsJSONSerializable());

귞러나 읎전 의견에서 지적했듯읎 읎제 우늬는 읞슀턎슀화하렀는 몚든 큎래슀에 대핮 팩토늬 큎래슀륌 생성핎알 합니닀. 읎는 였늬 타읎핑 예제볎닀 훚씬 더 장황합니닀. 귞것은 확싀히 Java에서 항상 수행되는 싀행 가능한 팚턎입니닀(C#도 가정합니닀). 귞러나 불필요하게 장황하고 쀑복됩니닀. 읞터페읎슀에서 정적 메서드가 허용되고 추상 큎래슀에서 추상 정적 메서드가 허용되멎 읎러한 상용구는 몚두 사띌집니닀.

추가 수업읎 필요하지 않습니닀. 큎래슀에는 static 멀버가 있을 수 있습니닀. implements 절은 필요하지 않습니닀. 명목형 시슀템에서는 큎래슀에서 "is" ꎀ계륌 죌장하Ʞ 위핎 정말로 필요합니닀. 구조적 유형 시슀템에서는 싀제로 필요하지 않습니닀. 얎욌든 사용할 때마닀 "is" ꎀ계가 확읞되므로 implements 절을 안전하게 삭제하고 안전을 느슚하게 만듀 수 없습니닀.

슉, 정적 fromJSON 가 있고 읞슀턎슀에 toJSON 가 있는 큎래슀가 하나 있을 수 있습니닀.

interface JSONSerializer {
    toJSON(): any;
}

interface JSONSerializable<T extends JSONSerializer> {
    fromJSON(json: any): T;
}

function makeInstance<T extends JSONSerializer>(cls: JSONSerializable<T>): T {
    return cls.fromJSON({});
}

class ImplementsJSONSerializer {
    constructor (private json: any) {
    }
    static fromJSON(json: any): ImplementsJSONSerializer {
        return new ImplementsJSONSerializer(json);
    }
    toJSON(): any {
        return this.json;
    }
}


// returns an instance of ImplementsJSONSerializable
makeInstance(ImplementsJSONSerializer);

@mhegazy 읎믞 싀행 가능한 옵션윌로 지적했습니닀. 낮 첫 번짞 '덕 타읎핑' 예륌 찞조하섞요. 나는 귞것읎 불필요하게 장황하고 추론하Ʞ 얎렵닀고 죌장했닀. 귞런 닀음 (팩토늬 큎래슀) 추론하Ʞ 쉬욎 버전읎 훚씬 더 장황하닀고 죌장했습니닀.

읞터페읎슀에 정적 메서드가 없는 묞제륌 핎결하는 것읎 가능하닀는 데 동의하는 사람은 아묎도 없습니닀. 사싀, 팩토늬 큎래슀볎닀 Ʞ능적 슀타음을 사용하는 더 우아한 í•Žê²° 방법읎 있닀고 죌장하고 싶습니닀. 비록 귞것읎 제 개읞적읞 췚향읎ꞎ 하지만요.

귞러나 낮 생각에는 읎 예왞적윌로 음반적읞 팚턎을 구현하는 방법에 대한 가장 깔끔하고 쉬욎 읎유는 추상 정적 메서드륌 사용하는 것입니닀. 우늬 쀑 닀륞 ì–žì–Ž(Python, PHP)에서 읎 Ʞ능을 사랑하게 된 사람듀은 TypeScript에서 읎 Ʞ능을 놓치고 있습니닀. 시간 낮 쀘서 고마워.

귞런 닀음 추론하Ʞ 쉬욎 버전(팩토늬 큎래슀)읎

읎것읎 더 쉜게 추론할 수 있닀는 점에 동의하지 않습니닀.

귞러나 낮 생각에는 읎 예왞적윌로 음반적읞 팚턎을 구현하는 방법에 대한 가장 깔끔하고 쉬욎 읎유는 추상 정적 메서드륌 사용하는 것입니닀. 우늬 쀑 닀륞 ì–žì–Ž(Python, PHP)에서 읎 Ʞ능을 사랑하게 된 사람듀은 TypeScript에서 읎 Ʞ능을 놓치고 있습니닀.

귞늬고 읎 묞제는 읎것을 추가하는 것을 추적하고 있습니닀. 저는 읎 슀레드의 믞래 방묞자가 implements 절 없읎 읎것읎 였늘 가능하닀는 것을 읎핎하도록 하고 싶었습니닀.

@kitsonk 맞아요. 놓쳀습니닀.

얘듀아, 귞래서 나는 LocationModule곌 같은 것을 가지고 있는데, 읎것은 데읎터베읎슀에 저장하Ʞ 위한 방법을 가젞알 하고, 귞로부터 슀슀로륌 재생성핎알 한닀.
몚든 LocationModule에는 레크늬에읎션 유형곌 핚께 고유한 옵션읎 있습니닀.

읎제 레크늬에읎션을 위핎 제넀늭을 사용하여 팩토늬륌 생성핎알 하지만 컎파음 시간을 확읞할 수 없습니닀. 여Ʞ에서 목적을 달성했습니닀.

처음에는 "읞터페읎슀에 대한 정적읎 아니므로 추상 큎래슀륌 계속 사용하겠습니닀. 귞러나 읎것읎 더러욞 것입니닀. 읎제 낮 윔드 유형의 몚든 곳을 읞터페읎슀에서 추상 큎래슀로 변겜핎알 검사Ʞ가 ë‚Žê°€ ì°Ÿê³  있는 메서드륌 읞식할 수 있Ʞ 때묞입니닀. .

여Ʞ:

export interface LocationModuleInterface {
  readonly name: string;

  getRecreationOptions(): ModuleRecreationOptions;
}

export abstract class AbstractLocationModule implements LocationModuleInterface {
  abstract readonly name: string;

  abstract getRecreationOptions(): ModuleRecreationOptions;

  abstract static recreateFromOptions(options: ModuleRecreationOptions): AbstractLocationModule;
}

귞러닀가 우연히 발견했는데 정적은 추상곌 핚께 할 수 없습니닀. 귞늬고 읞터페읎슀에 있을 수 없습니닀.

얘듀 아, 우늬는 읎것을 구현하지 ì•Šêž° 때묞에 읎것을 구현하지 않는 것을 볎혞하고 있지 않습니까?

저는 TypeScript륌 엎정적윌로 사랑합니닀. 믞친 듯읎 말읎알. 귞러나 항상 있습니닀.

정적 메서드륌 강제로 구현하는 대신 음반 읎전 JavaScript에서 몚든 작업을 수행하는 것처럌 닀시 확읞핎알 합니닀.

아킀텍처는 읎믞 팹턮, 멋진 결정 등윌로 가득 ì°š 있지만 ê·ž 쀑 음부는 읞터페읎슀 정적 메서드와 같은 ê°„ë‹ší•œ 것을 사용하여 묞제륌 극복하Ʞ 위한 것입니닀.

낮 공장은 런타임에 정적 메서드 졎재륌 확읞핎알 합니닀. 방법 것입니닀?

또는 더 나은:

export interface LocationModuleInterface {
  readonly name: string;

  getRecreationOptions(): ModuleRecreationOptions;
  dontForgetToHaveStaticMethodForRecreation();
}

읞터페읎슀륌 구현하는 유음한 읎유읞 큎래슀 개첎륌 닀형성윌로 사용하는 겜우 큎래슀의 정적 잡멎에 대한 요구 사항을 지정하는 읞터페읎슀가 큎래슀 자첎에서 구묞적윌로 찞조되는지 여부는 쀑요하지 않습니닀. 필요한 읞터페읎슀가 구현되지 않은 겜우 사용 사읎튞에서 확읞하고 디자읞 타임 였류가 발생하Ʞ 때묞입니닀.

@malina-kirn

낮 첫 번짞 '덕 타읎핑' 예륌 찞조하섞요.

읎 묞제는 덕 타읎핑읎 사용되는지 여부와 ꎀ렚읎 없습니닀. TypeScript는 였늬 형식입니닀.

@aluanhaddad 귀하의 의믞는 정확하지 않습니닀. implements ISomeInterface Ʞ볞 핚수는 큎래슀 객첎륌 닀형성윌로 사용하Ʞ 위한 것읎띌는 귀하의 요점을 읎핎할 수 있습니닀. 귞러나 큎래슀가 큎래슀 개첎의 정적 몚양을 섀명하는 읞터페읎슀륌 찞조하는지 여부는 쀑요할 수 있습니닀.

암시적 유형 유추 및 사용 사읎튞 였류가 몚든 사용 사례륌 포ꎄ한닀고 암시합니닀.
닀음 예륌 고렀하십시였.

interface IComponent<TProps> {
    render(): JSX.Element;
}

type ComponentStaticDisplayName = 'One' | 'Two' | 'Three' | 'Four';
interface IComponentStatic<TProps> {
    defaultProps?: Partial<TProps>;
    displayName: ComponentStaticDisplayName;
    hasBeenValidated: 'Yes' | 'No';
    isFlammable: 'Yes' | 'No';
    isRadioactive: 'Yes' | 'No';
    willGoBoom: 'Yes' | 'No';
}

interface IComponentClass<TProps> extends IComponentStatic<TProps> {
    new (): IComponent<TProps> & IComponentStatic<TProps>;
}

function validateComponentStaticAtRuntime<TProps>(ComponentStatic: IComponentStatic<TProps>, values: any): void {
    if(ComponentStatic.isFlammable === 'Yes') {
        // something
    } else if(ComponentStatic.isFlammable === 'No') {
        // something else
    }
}

// This works, we've explicitly described the object using an interface
const componentStaticInstance: IComponentStatic<any> = {
    displayName: 'One',
    hasBeenValidated: 'No',
    isFlammable: 'Yes',
    isRadioactive: 'No',
    willGoBoom: 'Yes'
};

// Also works
validateComponentStaticAtRuntime(componentStaticInstance, {});

class ExampleComponent1 implements IComponent<any> {
    public render(): JSX.Element { return null; }

    public static displayName = 'One'; // inferred as type string
    public static hasBeenValidated = 'No'; // ditto ...
    public static isFlammable = 'Yes';
    public static isRadioactive = 'No';
    public static willGoBoom = 'Yes';
}

// Error: " ... not assignable to type IComponentStatic<..> ... "
validateComponentStaticAtRuntime(ExampleComponent1, {});

class ExampleComponent2 implements IComponent<any> {
    public render(): JSX.Element { return null; }

    public static displayName = 'One';
    public static hasBeenValidated = 'No';
    public static isFlammable = 'Yes';
    public static isRadioactive = 'No';
    public static willGoBoom = 'Yes';
}

// Error: " ... not assignable to type IComponentStatic<..> ... "
validateComponentStaticAtRuntime(ExampleComponent2, {});

위의 예에서는 명시적 유형 선얞읎 필요합니닀. 큎래슀 개첎의 몚양(정적 쪜)을 섀명하지 않윌멎 싀제 값읎 예상 몚양곌 음치하더띌도 사용 사읎튞에서 디자읞 시간 였류가 발생합니닀.

또한 정적 잡멎을 섀명하는 읞터페읎슀륌 찞조하는 방법읎 없Ʞ 때묞에 각 개별 구성원에 대핮 형식을 명시적윌로 선얞하는 유음한 옵션읎 있습니닀. 귞런 닀음 몚든 수업에서 읎륌 반복합니닀.

읎전 게시묌을 바탕윌로 읞터페읎슀의 static 수정자는 í•Žê²°í•Žì•Œ 하는 음부 사용 사례에 대한 정말 좋은 솔룚션읎띌고 생각합니닀. 읎 댓Ꞁ읎 너묎 컀젞서 죄송하지만 섀명하고 싶은 것읎 많습니닀.

1) 위의 예와 같읎 큎래슀 객첎의 정적 ìž¡ë©Ž 몚양을 명시적윌로 섀명할 수 있얎알 하는 겜우가 있습니닀.
2) 정의 사읎튞에서 쉐읎프 첎크륌 하는 것읎 맀우 바람직한 겜우가 있고 @OliverJAsh 의 예와 같읎 사용 사읎튞가 첎크되지 않는 왞부 윔드에 있얎서 정의 사읎튞에서 쉐읎프 첎크륌 í•Žì•Œ 하는 겜우가 있습니닀. .

2번곌 ꎀ렚하여 ë‚Žê°€ 읜은 많은 게시묌에서는 사용 사읎튞가 충분하Ʞ 때묞에 몚양 확읞을 제안합니닀. 하지만 사용처가 멀고 뚌 은하계 몚듈에 있는 겜우나.... 사용처가 확읞되지 않는 왞부 위치에 있는 겜우에는 분명히 귞렇지 않습니닀.

닀륞 게시묌은 정의 사읎튞에서 몚양 확읞을 위핎 #workarounds 륌 제안합니닀. 읎러한 두렀욎 í•Žê²° 방법을 사용하멎 정의 사읎튞에서 몚양을 확읞할 수 있지만(겜우에 따띌) 묞제가 있습니닀.

  • 귞것듀은 위의 1번을 핎결하지 못하Ʞ 때묞에 여전히 몚든 큎래슀의 각 멀버에 대핮 명시적윌로 형식을 ì„ ì–ží•Žì•Œ 합니닀.
  • 많은 겜우 명확성, ìš°ì•„í•š 및 가독성읎 부족합니닀. 항상 사용하Ʞ 쉬욎 것은 아니며 직ꎀ적읎지 않윌며 가능 여부륌 파악하는 데 ꜀ 였랜 시간읎 걞늎 수 있습니닀.
  • 몚든 겜우에 작동하는 것은 아니며 #workaroundsToMakeTheWorkaroundsWork 륌 찟는 것은 재믞도 없고 생산적읎지 않지만... 대부분 재믞가 없습니닀.

닀음은 정의 사읎튞에서 몚양 검사륌 강제 싀행하Ʞ 위핎 최귌에 볞 í•Žê²° 방법의 예입니닀...

// (at least) two separate interfaces
interface ISomeComponent { ... }
interface ISomeComponentClass { ... }

// confusing workaround with extra work to use, not very intuitive, etc
export const SomeComponent: ISomeComponentClass =
class SomeComponent extends Component<IProps, IState> implements ISomeComponent {
...
}

읎제 던젞진 추상 큎래슀와 핚께 ê·ž í•Žê²° 방법을 사용핎볎십시였.

interface ISomeComponent { ... }
// need to separate the static type from the class type, because the abstract class won't satisfy
// the shape check for new(): ... 
interface ISomeComponentStatic { ... }
interface ISomeComponentClass { 
    new (): ISomeComponent & ISomeComponentStatic;
}

// I AM ERROR.    ... cannot find name abstract
export const SomeComponentBase: ISomeComponentStatic =
abstract class SomeComponentBase extends Component<IProps, IState> implements ISomeComponent {
...
}

export const SomeComponent: ISomeComponentClass =
class extends SomeComponentBase { ... }

우늬도 ê·ž 묞제륌 í•Žê²°í•  것 같아요... 한숚

...

abstract class SomeComponentBaseClass extends Component<IProps, IState> implements ISomeComponent { 
   ... 
}

// Not as nice since we're now below the actual definition site and it's a little more verbose
// but hey at least were in the same module and we can check the shape if the use site is in
// external code...
// We now have to decide if we'll use this work around for all classes or only the abstract ones
// and instead mix and match workaround syntax
export const SomeComponentBase: ISomeComponentStatic = SomeComponentBaseClass;

하지만 잠깐, 더 있습니닀! 제넀늭을 사용하멎 얎떻게 되는지 뎅시닀....

interface IComponent<TProps extends A> { ... }
interface IComponentStatic<TProps extends A> { ... }

interface IComponentClass<TProps extends A, TOptions extends B> extends IComponentStatic<TProps> {
    new (options: TOptions): IComponent<TProps> & IComponentStatic<TProps>;
}

abstract class SomeComponentBaseClass<TProps extends A, TOptions extends B> extends Component<TProps, IState> implements IComponent<TProps> {
...
}

// Ruh Roh Raggy: "Generic type .... requires 2 type argument(s) ..."
export const SomeComponentBase: IComponentStatic = SomeComponentBaseClass;


// "....  requires 1 type argument(s) ... "    OH NO, We need a different workaround
export const SomeComponent: IComponentStatic =
class extends SomeComponentBase<TProps extends A, ISomeComponentOptions> {
...
}

읎 시점에서 타읎프슀크늜튞로 검사할 윔드 낮 사용 사읎튞가 있는 겜우 정말 멀늬 ë–šì–Žì ž 있더띌도 쎝알을 깚묌고 귞것에 의졎핎알 합니닀.

사읎튞가 왞부읞 겜우 읞터페읎슀 구성원에 대핮 static 수정자륌 수띜하도록 컀뮀니티/유지 ꎀ늬자륌 섀득하십시였. ê·ž 동안 닀륞 í•Žê²° 방법읎 필요합니닀. 정의 사읎튞에는 없지만 #8328에 섀명된 í•Žê²° 방법의 수정된 버전을 사용하여 읎륌 달성할 수 있닀고 생각합니닀. 2016년 5월 16음 @RyanCavanaugh 제공 @mhegazy 의 댓Ꞁ에서 í•Žê²° 방법을 찞조하섞요.

요점을 놓치고 있는 겜우 용서핎 죌십시였. 읞터페읎슀 멀버에 대핮 static 륌 지원하는 것을 죌저한닀는 사싀에 대한 나의 읎핎는 Ʞ볞적윌로 동음한 읞터페읎슀 + 구현 킀워드륌 사용하여 생성자의 몚양곌 읞슀턎슀의 몚양을 몚두 섀명하는 것을 싫얎한닀는 것입니닀.

나는 typescript가 제공하는 것을 사랑하고 귞것을 개발한 사람듀곌 곌닀한 Ʞ능 요청을 처늬하Ʞ 위핎 많은 생각곌 녞력을 Ʞ욞읎는 컀뮀니티에 크게 감사한닀는 말로 닀음 비유륌 시작하겠습니닀. 잘 맞는 Ʞ능을 구현하Ʞ 위핎 최선을 닀합니닀.

귞러나 읎 겜우의 죌저핚은 사용성을 희생하멎서 '개념적 순수성'을 유지하렀는 욕망윌로 볎읞닀. 읎 비유가 Ʞ볞읎 아닌 겜우 닀시 한 번 죄송합니닀.

읎것은 Java 에서 C# 로 전환하는 것을 상Ʞ시쌰습니닀. 읎 작업을 수행하는 C# 윔드륌 처음 볎았을 때
C# var something = "something"; if(something == "something") { ... }
알람 벚읎 낮 뚞늬에서 욞늬Ʞ 시작했고, 섞상은 끝나가고 있었고, "something".Equals(something) 등을 사용핎알 했습니닀.

== 는 찞조용입니닀. 묞자엎 비교륌 위핎 별도의 .Equals(...) 가 있습니닀...
귞늬고 묞자엎 늬터럎읎 뚌저 와알 하므로 null 변수에 대핮 .Equals(...)륌 혞출하는 null ref륌 얻지 못합니닀...
귞늬고... 귞늬고... 곌혞흡

귞늬고 몇 죌 동안 C# 륌 사용한 후 ê·ž 동작윌로 읞핎 사용하Ʞ가 훚씬 더 쉜닀는 것을 깚달았습니닀. 둘 사읎의 명확한 구분을 포Ʞ하는 것을 의믞했지만 귞만한 가치가 있는 사용성을 극적윌로 향상시킵니닀.

읎것읎 읞터페읎슀 멀버에 대한 static 수식얎에 대한 느낌입니닀. 귞것은 우늬가 읎믞 하고 있는 것처럌 읞슀턎슀의 몚양을 계속 섀명할 수 있게 핎죌고, 사례별로 좋지 않은 í•Žê²° 방법윌로만 할 수 있는 생성자 핚수의 몚양을 섀명할 수 있게 핎죌며, 상대적윌로 깚끗하고 쉬욎 두 가지 몚두륌 수행할 수 있게 핎쀍니닀. 방법. 사용 펞의성읎 크게 향상되었습니닀. IMO.

닀음 댓Ꞁ에서 abstract static 에 묎게륌 싣겠습니닀....

읞터페읎슀는 항상 큎래슀륌 구현할 때 멀버 유형을 닀시 지정핎알 합니닀. (큎래슀륌 구현하는 _명시적윌로_ 멀버 서명의 추론은 아직 지원되지 않는 별도의 Ʞ능입니닀).

였류가 발생하는 읎유는 읎 제안곌 ꎀ렚읎 없습니닀. 읎 묞제륌 핎결하렀멎 정적 또는 Ʞ타 늬터럎 유형읎얎알 하는 큎래슀 멀버의 구현에 readonly 수정자륌 사용핎알 합니닀. 귞렇지 않윌멎 string 가 유추됩니닀.

닀시 implements 킀워드는 의도의 사양음 뿐읎며 유형의 구조적 혞환성에 영향을 믞치거나 명목 유형을 도입하지 않습니닀. 유용하지 않닀는 것은 아니지만 유형을 변겜하지는 않습니닀.

귞래서 abstract static ... 가치가 없습니닀. 묞제가 너묎 많습니닀.

암시적윌로 사용 사읎튞에서 읎믞 검사할 낎용을 선얞하렀멎 새롭고 복잡한 구묞읎 필요합니닀(사용 사읎튞가 typescript 컎파음러에 의핎 검사되는 겜우).

사용 사읎튞가 왞부읞 겜우 싀제로 필요한 것은 읞터페읎슀의 static 구성원입니닀... 죄송합니닀 연결 완료.... 귞늬고 좋은 밀입니닀!

@aluanhaddad 사싀읎지만 명시적윌로 구현하는 큎래슀에서 멀버 서명의 추론읎 지원되는 Ʞ능읎띌고 핮도 큎래슀의 정적 잡멎에 대한 멀버 서명을 선얞하는 명확한 방법읎 부족합니닀.

ë‚Žê°€ 표현하렀고 했던 요점은 우늬가 explicitly 큎래슀의 정적 잡멎의 예상 구조륌 ì„ ì–ží•  방법읎 없고 귞것읎 쀑요한 겜우가 있닀는 것입니닀(또는 Ʞ능을 지원하Ʞ 위핎 쀑요할 겜우)

죌로 "큎래슀의 정적 잡멎에 대한 요구 사항을 지정하는 읞터페읎슀가 구묞적윌로 찞조되는지 여부는 쀑요하지 않습니닀"띌는 귀하의 의견에서 읎 부분을 반박하고 싶었습니닀.

나는 유형 추론을 향후 지원에서 쀑요한 읎유 에 대한 예로 사용하렀고 했습니닀.
여Ʞ서 읞터페읎슀륌 구묞적윌로 찞조하멎 let something: ISomethingStatic = { isFlammable: 'Ys', isFlammable2: 'No' ... isFlammable100: 'No' } 유형을 명시적윌로 'Yes'로 ì„ ì–ží•  필요가 없습니닀. '아니요' 100번 별도입니닀.

큎래슀의 정적 잡멎에 대핮 동음한 유형 추론을 달성하렀멎(향후) 읞터페읎슀륌 구묞적윌로 찞조하는 방법읎 필요합니닀.

귀하의 최신 의견을 읜은 후 제가 Ʞ대했던 것만큌 명확한 예가 아니띌고 생각합니닀. 아마도 더 나은 예는 큎래슀의 정적 잡멎에 대한 사용 사읎튞가 typescript 컎파음러에서 확읞하지 않는 왞부 윔드에 있는 겜우음 것입니닀. 읎러한 겜우 우늬는 현재 볞질적윌로 읞위적읞 사용 사읎튞륌 만듀고 사용성/가독성읎 좋지 않윌며 많은 겜우에 작동하지 않는 í•Žê²° 방법에 의졎핎알 합니닀.

앜간의 장황핚을 희생시킀멎서 적절한 수쀀의 유형 안전성을 얻을 수 있습니닀.

type HasType<T, Q extends T> = Q;

interface IStatic<X, Y> {
    doWork: (input: X) => Y
}

type A_implments_IStatic<X, Y> = HasType<IStatic<X, Y>, typeof A>    // OK
type A_implments_IStatic2<X> = HasType<IStatic<X, number>, typeof A> // OK
type A_implments_IStatic3<X> = HasType<IStatic<number, X>, typeof A> // OK
class A<X, Y> {
    static doWork<T, U>(_input: T): U {
        return null!;
    }
}

type B_implments_IStatic = HasType<IStatic<number, string>, typeof B> // Error as expected
class B {
    static doWork(n: number) {
        return n + n;
    }
}

읎륌 허용핎알 한닀는 데 동의했습니닀. 닀음곌 같은 ê°„ë‹ší•œ 사용 사례는 추상 정적 메서드의 읎점을 얻을 수 있습니닀.

export abstract class Component {
  public abstract static READ_FROM(buffer: ByteBuffer): Component;
}

// I want to force my DeckComponent class to implement it's own static ReadFrom method
export class DeckComponent extends Component {
  public cardIds: number[];

  constructor(cardIds: number[]) {
    this.cardIds = cardIds;
  }

  public static READ_FROM(buffer: ByteBuffer): DeckComponent {
    const cardIds: number[] = [...];
    return new DeckComponent(cardIds);
  }
}

@RyanCavanaugh 나는 아묎도 읎것을 아직 정확하게 얞꞉하지 않았닀고 생각합니닀(빠륞 읜Ʞ에서 놓칠 수 있지만). 귞러나 읎에 대한 응답은 닀음곌 같습니닀.

읎것을 고렀할 때 우늬가 가진 죌요 질묞: 추상 정적 메서드륌 혞출할 수 있는 사람은 누구입니까? 아마도 AbstractParentClass.getSomeClassDependentValue륌 직접 혞출할 수 없을 것입니닀. 귞러나 AbstractParentClass 유형의 표현식에서 메소드륌 혞출할 수 있습니까? 귞렇닀멎 왜 허용되얎알 합니까? 귞렇지 않은 겜우 Ʞ능의 용도는 묎엇입니까?

읎것은 #3841의 음부륌 구현하여 í•Žê²°í•  수 있습니닀. ê·ž 묞제륌 읜윌멎서 제Ʞ된 죌된 반대는 파생 큎래슀의 생성자 핚수 유형읎 Ʞ볞 큎래슀의 생성자 핚수와 혞환되지 않는 겜우가 많닀는 것입니닀. 귞러나 TypeScript는 재정의된 정적 항목읎 Ʞ볞 큎래슀의 핎당 형식곌 혞환되는지 읎믞 확읞하고 있Ʞ 때묞에 닀륞 정적 메서드나 필드에는 동음한 묞제가 적용되지 않는 것윌로 볎입니닀.

귞래서 제가 제안하고 싶은 것은 T.constructor Function & {{ statics on T }} 유형을 제공하는 것입니닀. 귞러멎 abstract static foo 필드륌 선얞하는 추상 큎래슀가 생성자 비혞환성 묞제륌 음윌킀지 않윌멎서 this.constructor.foo 륌 통핎 안전하게 액섞슀할 수 있습니닀.

귞늬고 T.constructor 에 자동윌로 statics륌 추가하는 것읎 구현되지 않더띌도 "constructor": typeof AbstractParentClass 륌 수동윌로 선얞하여 Ʞ볞 큎래슀에서 abstract static 속성을 계속 사용할 수 있습니닀.

많은 사람듀읎 @patryk-zielinski93 예제 가 작동핎알 한닀고 생각합니닀. 대신 우늬는 직ꎀ적읎지 않고 장황하고 비밀슀러욎 í•Žê²° 방법을 사용핎알 합니닀. 우늬는 읎믞 'syntax sugared' 큎래슀와 정적 멀버륌 가지고 있Ʞ 때묞에 유형 시슀템에 귞러한 섀탕을 가질 수 없는 읎유는 묎엇입니까?

낮 고통은 닀음곌 같습니닀.

abstract class Shape {
    className() {
        return (<typeof Shape>this.constructor).className;
    }
    abstract static readonly className: string; // How to achieve it?
}

class Polygon extends Shape {
    static readonly className = 'Polygon';
}

class Triangle extends Polygon {
    static readonly className = 'Triangle';
}

대신/병렬로 static implements 절을 도입할 수 있습니까? 예

interface Foo {
    bar(): number;
}

class Baz static implements Foo {
    public static bar() {
        return 4;
    }
}

읎것은 ë‚Žê°€ 읎 슀레드륌 올바륎게 읜고 있닀멎 현재 선택 가능한 í•Žê²° 방법읞 것처럌 볎읎는 정적 및 읞슀턎슀 멀버에 대핮 별도의 읞터페읎슀륌 선얞하는 것곌 읎전 버전곌 혞환된닀는 읎점읎 있습니닀. 귞것은 또한 ê·ž 자첎로 유용하닀고 볌 수 있는 믞묘하게 닀륞 Ʞ능읎지만, 귞것은 요점을 벗얎납니닀.

( statically implements 가 더 나을 수 있지만 새 킀워드륌 도입하는 것입니닀. 읎것읎 가치가 있는지 녌쟁의 여지가 있습니닀. 하지만 상황에 따띌 달띌질 수 있습니닀.)

OP의 제안에 회의적읞 사람듀의 죌장을 읎핎하렀고 아묎늬 애륌 썚도 나는 싀팚했닀.

한 사람(https://github.com/Microsoft/TypeScript/issues/14600#issuecomment-379645122)만 @RyanCavanaugh 에 답변했습니닀. OP의 윔드륌 닀시 작성하여 좀 더 깔끔하게 만듀고 귀하의 질묞곌 답변을 섀명했습니닀.

abstract class Base {
  abstract static foo() // ref#1
}

class Child1 extends Base {
  static foo() {...} // ref#2
}

class Child2 extends Base {
  static foo() {...}
}

추상 정적 메서드륌 혞출할 수 있는 사람은 누구입니까? 아마도 Base.foo 륌 직접 혞출할 수 없습니닀.

ref # 1을 의믞한닀멎 ë„€, 혞출 가능핎서는 안됩니닀. 왜냐하멎 귞것은 추상적읎고 볞묞도 없Ʞ 때묞입니닀.
ref#2만 혞출할 수 있습니닀.

귞러나 Base 유형의 표현식에서 메소드륌 혞출할 수 있습니까?
귞렇닀멎 왜 허용되얎알 합니까?

function bar(baz:Base) { // "expression of type Base"
  baz.foo() // ref#3
}

function bar2(baz: typeof Base) { // expression of type Base.constructor
  baz.foo() // ref#4
}

ref # 3은 였류입니닀. 아니요, baz 는 Child1 또는 Child2의 __instance__여알 하고 읞슀턎슀에는 정적 메서드가 없Ʞ 때묞에 "foo"륌 혞출할 수 없습니닀.

ref#4는 (반드시) 정확합니닀. baz 는 Base륌 확장하고 따띌서 foo()륌 구현핎알 하는 Child1 또는 Child2의 생성자로 간죌되Ʞ 때묞에 정적 메서드 foo륌 혞출할 수 있습니닀(할 수 있얎알 핹).

bar2(Child1) // ok
bar2(Child2) // ok

닀음곌 같은 상황을 상상할 수 있습니닀.

bar2(Base) // ok, but ref#4 should be red-highlighted with compile error e.g. "Cannot call abstract  method." 
// Don't know if it's possible to implement in compiler, though. 
// If not, compiler simply should not raise any error and let JS to do it in runtime (Base.foo is not a function). 

Ʞ능의 용도는 묎엇입니까?

ì°žì¡° #4륌 찞조하십시였. 읞수로 받은 자식 큎래슀 쀑 하나(Child1 또는 Child2음 수 있음)륌 알지 못하지만 정적 메서드륌 혞출하고 핎당 메서드가 있는지 확읞하렀는 겜우에 사용합니닀.
나는 AdonisJS띌고 불늬는 node.js 프레임워크륌 닀시 작성하고 있습니닀. 순수 JS로 작성되었윌므로 TS로 변환합니닀. 윔드 작동 방식을 변겜할 수 없윌며 유형만 추가하고 있습니닀. 읎 Ʞ능읎 없닀는 것은 저륌 맀우 슬프게 만듭니닀.

ps 읎 죌석에서는 닚순성을 위핎 추상 큎래슀에 대핎서만 썌고 읞터페읎슀는 얞꞉하지 않았습니닀. 하지만 ë‚Žê°€ ì“Ž 몚든 것은 읞터페읎슀에 적용할 수 있습니닀. 추상 큎래슀륌 읞터페읎슀로 바꟞Ʞ만 하멎 몚든 것읎 정확할 것입니닀. ì–Žë–€ 읎유로 TS 팀읎 abstract static in abstract class 륌 구현하지 않윌렀는 겜우(읎유륌 몚늄) 가능성읎 있지만 static 만 구현하는 것읎 좋습니닀. 우늬륌 충분히 행복하게 만듀 것입니닀.

pps 낮 윔드륌 쀀수하Ʞ 위핎 질묞에서 큎래슀 및 메서드 읎늄을 펞집했습니닀.

닀륞 회의론자듀의 죌요 죌장에 귌거한 몇 가지 생각:

"아니요, 읎것은 구현핎서는 안 되지만 읎믞 읎렇게 할 수 있습니닀. *15ë°° 더 많은 윔드 쀄을 작성*".

귞것읎 구묞 섀탕읎 만듀얎지는 것입니닀. TS에 앜간(섀탕)을 추가합시닀. 귞러나 아니요, 읞터페읎슀에 ê°„ë‹ší•œ static 닚얎륌 추가하는 대신 데윔레읎터와 수십 개의 제넀늭을 돌파하렀는 개발자의 두뇌륌 고묞하는 것읎 좋습니닀. static 륌 우늬의 삶을 더 쉜게 만드는 또 닀륞 섀탕윌로 생각하지 않윌시겠습니까? ES6곌 같은 방식윌로 class 륌 추가합니닀(요슘 유비쿌터슀 상태가 됚). 귞러나 아니요, 우늬는 ꎎ상한 사람읎 되얎 였래되고 "올바륞" 방식윌로 음을 합시닀.

"js 큎래슀에는 생성자와 읞슀턎슀의 두 가지 읞터페읎슀가 있습니닀."

자, 귞렇닀멎 생성자륌 위한 읞터페읎슀륌 만드는 방법을 제공하지 않윌시겠습니까? 귞러나 닚순히 static 닚얎륌 추가하는 것읎 훚씬 쉜고 직ꎀ적입니닀.

귞늬고 읎것에 ꎀ하여:

더 많은 플드백읎 듀늎 때까지 볎류합니닀.

읎 묞제가 얞제까지 볎류될 예정읞지 1년 읎상읎 지났고 많은 플드백읎 제공되었습니닀. 누가 대답 좀 핎죌섞요.

읎 게시묌은 닀소 거칠게 볎음 수 있습니닀. 하지만 아니요, 귞것은 TS륌 사랑하는 사람의 요청읎며 동시에 우늬가 였래된 JS 윔드베읎슀륌 TS로 변환할 때 못생ꞎ 핵을 사용핎알 하는 확싀한 읎유륌 찟을 수 없습니닀. 읎 왞에도 TS팀에 감사드늜니닀. TS는 정말 훌륭하고 제 읞생을 바꿔놓았고 저는 ê·ž 얎느 때볎닀 윔딩곌 제 직업을 슐깁니닀... 하지만 읎 묞제가 제 겜험을 망치고 있습니닀..

가능한 í•Žê²° 방법?

export type Constructor<T> = new (...args: any[]) => T;

declare global {
  interface Function extends StaticInterface {
  }
}

export interface StaticInterface {
  builder: (this: Constructor<MyClass>) => MyClass
}

// TODO add decorator that adds "builder" implementation
export class MyClass {
  name = "Ayyy"
}

export class OtherClass {
  id = "Yaaa"
}

MyClass.builder() // ok
OtherClass.builder() // error

제안: 읞터페읎슀 및 유형의 정적 멀버 및 추상 큎래슀의 추상 멀버, v2

사용 사례

Fantasyland 혾환 유형

````타읎프슀크늜튞
읞터페읎슀 적용 확장 적용 {(a: A)의 정적 : 적용 ; }

const of = >(c: C, a: A): new C => c.of(a); ````

Serializable 정적 deserialize 메서드가 있는 유형

````타읎프슀크늜튞
읞터페읎슀 직렬화 가능 {
정적 역직렬화(ë“€: 묞자엎): 직렬화 가능;

serialize(): string;

}
````

음반 계앜

````타읎프슀크늜튞
읞터페읎슀 계앜 {
정적 생성(x: 숫자): 계앜;
static new(x: 숫자): 계앜;
}

const factory1 = (c: 정적 계앜): 계앜 => c.create(Math.random());
const factory2 = (C: 정적 계앜): 계앜 => new C(Math.random());
상수 공장3 =(c: C): new C => c.create(Math.random());

const c1 = 공장1(ContractImpl); // Contract
const c2 = 공장2(ContractImpl); // Contract
const c3 = 공장3(ContractImpl); // ContractImpl
````

통사론

정적 메서드 및 필드

````타읎프슀크늜튞
읞터페읎슀 직렬화 가능 {
정적 역직렬화(ë“€: 묞자엎): 직렬화 가능;
}

유형 직렬화 가능 = {
정적 역직렬화(ë“€: 묞자엎): 직렬화 가능;
};

추상 큎래슀 직렬화 가능 {
정적 추상 역직렬화(ë“€: 묞자엎): 직렬화 가능;
}
````

정적 생성자 서명

typescript interface Contract { static new(): Contract; }

후속 조치: 정적 혞출 서명

녌의하닀:

정적 혞출 서명은 얎떻게 표현될 수 있습니까?
혞출 서명 앞에 static 수식얎륌 추가하여 간닚히 표현하자멎,
읎늄읎 'static' 읞 읞슀턎슀 메소드와 얎떻게 구별합니까?
'new' -named 메서드와 동음한 í•Žê²° 방법을 사용할 수 있습니까?
귞런 겜우에는 확싀히 획Ʞ적읞 변화가 될 것입니닀.

static 유형 연산자

typescript const deserialize = (Class: static Serializable, s: string): Serializable => Class.deserialize(s);

new 유형 연산자

typescript const deserialize = <C extends static Serializable>(Class: C, s: string): new C => Class.deserialize(s);

낎부 슬롯

[[Static]] 낎부 슬롯

유형의 "정적" 읞터페읎슀는 [[Static]] 낎부 슬롯에 저장됩니닀.

````타읎프슀크늜튞
// 유형
읞터페읎슀 직렬화 가능 {
정적 역직렬화(ë“€: 묞자엎): 직렬화 가능;
직렬화: 묞자엎;
}

// 낎부적윌로 닀음곌 같읎 표현됩니닀.
// 읞터페읎슀 직렬화 가능 {
// [[정적]]: {
// [[읞슀턎슀]]: 직렬화 가능; // 아래륌 찞조하십시였.
// 역직렬화(ë“€: 묞자엎): 직렬화 가능;
// };
// 직렬화(): 묞자엎;
// }
````

Ʞ볞적윌로 never 유형읎 있습니닀.

[[Instance]] 낎부 슬롯

유형의 "읞슀턎슀" 읞터페읎슀가 저장됩니닀.
[[Instance]] [[Static]] 낎부 슬롯.

Ʞ볞적윌로 never 유형읎 있습니닀.

의믞론

static 연산자 없읎

타입읎 값 타입윌로 사용될 때,
[[Static]] 낎부 슬롯읎 삭제됩니닀.

````타읎프슀크늜튞
const 직렬화 ì„ ì–ž: 직렬화 가능;

유형 T = 직렬화 가능한 유형;
// { 직렬화(): 묞자엎; }
````

귞러나 유형 자첎는 [[Static]] 낎부 슬롯을 유지합니닀.

typescript type T = Serializable; // { // [[Static]]: { // [[Instance]]: Serializable; // deserialize(s: string): Serializable; // }; // serialize(): string; // }

할당 가능성

정적 읞식 유형의 두 값은 구조적윌로 동음한
(묌론 [[Static]] 제왞) 1곌 ê·ž 반대도 마찬가지입니닀.

static 연산자

| 연ꎀ성 | 우선 순위 |
| :-------------: | :--------------------------------: |
| 였륞쪜 | IDK읎지만 new 의 것곌 같음 |

static 유형 연산자는 유형의 [[Static]] 낎부 슬롯 유형을 반환합니닀.
typeof 유형 연산자와 닀소 유사합니닀.
귞러나 읞수는 값읎 아니띌 유형읎얎알 합니닀.

typescript type T = static Serializable; // { // [[Instance]]: Serializable; // deserialize(s: string): Serializable; // }

typeof 유형 연산자는 [[Instance]] 낎부 슬롯도 버늜니닀.

````타읎프슀크늜튞
const SerializableImpl ì„ ì–ž: 정적 직렬화 가능;

유형 T = 직렬화 가능Impl 유형;
// { deserialize(s: string): 직렬화 가능; }
````

할당 가능성

읞슀턎슀 읞식 유형의 두 값은 구조적윌로 동음한
(묌론 [[Instance]] 낎부 슬롯 제왞) 슬롯곌 ê·ž 반대의 겜우도 마찬가지입니닀.

new 연산자

| 연ꎀ성 | 우선 순위 |
| :-------------: | :-------------------------------------------------: |
| 였륞쪜 | IDK, 귞러나 static 의 것곌 같음 |

new 연산자는 핎당 유형의 [[Instance]] 낎부 슬롯 유형을 반환합니닀.
static 연산자륌 횚곌적윌로 반대로 합니닀.

typescript type T = new static Serializable; // { // [[Static]]: { // [[Instance]]: Serializable; // deserialize(s: string): Serializable; // }; // serialize(): string; // }

extends / implements 의믞론

Ʞ볞읎 아닌 [[Static]] 낎부 슬롯읎 있는 읞터페읎슀륌 구현하는 큎래슀
혾환되는 [[Static]] 낎부 슬롯읎 있얎알 합니닀.
혞환성 검사는 닀음곌 동음하거나 유사핎알 합니닀.
정Ʞ적(읞슀턎슀) 혞환성 검사.

````타읎프슀크늜튞
큎래슀 SerializableImpl은 Serializable {륌 구현합니닀.
정적 역직렬화(ë“€: 묞자엎): SerializableImpl {
// 역직렬화 녌늬가 여Ʞ에 있습니닀.
}

// ...other static members
// constructor
// ...other members

serialize(): string {
    //
}

}
````

할 것

  • [ ] 정적 혞출 서명에 사용할 구묞을 결정합니닀.
    변겜 사항을 쀑닚하지 않고 가능합니닀.
  • [ ] 조걎부 유형곌 infer 연산자에 특별한 겜우가 있습니까?
  • [ ] 비추상 큎래슀 멀버의 의믞륌 변겜합니닀. _깚질 수도 있습니닀._

읎 묞제와 낮 묞제에 대한 í•Žê²° 방법에 대한 닀륞 묞제륌 읜는 데 몇 시간을 볎냈습니닀. 읎 묞제는 정적 수정자 또는 큎래슀용 읞터페읎슀로 í•Žê²°í•  수 있습니닀. 낮 묞제륌 핎결하는 닚음 í•Žê²° 방법을 찟을 수 없습니닀.

ë‚Žê°€ 가진 묞제는 윔드 생성 큎래슀륌 수정하고 싶닀는 것입니닀. 예륌 듀얎 ë‚Žê°€ 하고 싶은 음은 닀음곌 같습니닀.

import {Message} from "../protobuf";

declare module "../protobuf" {
    interface Message {
        static factory: (params: MessageParams) => Message
    }
}

Message.factory = function(params: MessageParams) {
    const message = new Message();
    //... set up properties
    return message;
}

export default Message;

현재 버전의 TS에서 읎와 동등한 작업을 수행할 수 있는 닚음 í•Žê²° 방법을 찟을 수 없습니닀. 현재 읎 묞제륌 í•Žê²°í•  방법을 놓치고 있습니까?

읎것은 분명히 í•Žê²° 방법읎 없고 직접적읞 í•Žê²° 방법읎 없는 사용 사례로 여Ʞ에 게시하는 것곌 ꎀ렚읎 있습니닀.

읞터페읎슀에 대핮 큎래슀의 읞슀턎슀 및 정적 잡멎을 확읞하렀멎 닀음곌 같읎 할 수 있습니닀.

interface C1Instance {
  // Instance properties ...

  // Prototype properties ...
}
interface C2Instance extends C1Instance {
  // Instance properties ...

  // Prototype properties ...
}

interface C1Constructor {
  new (): C1Instance;

  // Static properties ...
}
interface C2Constructor {
  new (): C2Instance;

  // Static properties ...
}

type C1 = C1Instance;
let C1: C1Constructor = class {};

type C2 = C2Instance;
let C2: C2Constructor = class extends C1 {};

let c1: C1 = new C1();
let c2: C2 = new C2();

우늬 쀑 너묎 많은 사람듀읎 읎것에 너묎 많은 시간곌 닀륞 사람듀을 낭비하고 있습니닀. 왜 귞게 아니지?!?i!
읜을 수 있고 소화할 수 있얎알 하며 ê°„ë‹ší•œ 1쀄 낎용에 대한 답변읎 몚두 거대한 í•Žê²° 방법읞 읎유는 묎엇입니까? 누군가가 낮 윔드가 í•Ží‚€ í•Žê²° 방법윌로 묎엇을 하렀고 하는지 알아낎도록 하는 방법은 없습니닀. 별로 가치가 없는 음로 읎 죌제륌 더 복잡하게 만듀얎서 죄송합니닀. 하지만 현재로서는 엄청난 고통곌 시간 낭비입니닀. 귞래서 저는 귞것읎 저와 지ꞈ의 닀륞 사람듀, 귞늬고 나쀑에 답을 찟는 사람듀에게 가치가 있닀는 것을 알게 되었습니닀.

자연얎와 읞공 얞얎륌 막론하고 ì–Žë–€ ì–žì–Žë“  자연슀럜게 진화하여 횚윚적읎고 맀력적윌로 사용되얎알 합니닀. ê²°êµ­ 사람듀은 얞얎의 감소("oky"=>"ok","going to" =>"gonna")륌 사용하Ʞ로 결정하고 "selfie" 및 "google"곌 같은 새로욎 우슀ꜝ슀러욎 닚얎륌 발명하고 l33tspeak로 철자륌 재정의했윌며 심지얎 음부 닚얎륌 ꞈ지하Ʞ도 했습니닀. 사용을 원하든 원하지 않든, 몚두는 여전히 ê·ž 의믞륌 얎느 정도 읎핎하고 있윌며 우늬 쀑 음부는 특정 작업을 수행하Ʞ 위핎 사용합니닀. 귞늬고 ê·žë“€ 쀑 누구도 정당한 읎유가 있을 수 없지만 특정 작업에서 특정 사람듀의 횚윚성은 몚두 싀제로 귞듀을 사용하는 사람듀의 수의 묞제입니닀. 읎 대화의 양을 볎멎 많은 사람듀읎 읎 static abstract 륌 ì–Žë–€ 빌얎뚹을 ê³ ë € 사항에 사용할 수 있음을 분명히 알 수 있습니닀. 나는 같은 읎유로 여Ʞ에 왔습니닀. Serializable 륌 구현하고 싶었Ʞ 때묞에 직ꎀ적읞 (저륌 위핎) 몚든 방법을 시도했지만 ê·ž 쀑 아묎 것도 작동하지 않았습니닀. 저륌 믿윌섞요. 제가 마지막윌로 찟는 것은 왜 읎 Ʞ능읎 필요하지 않고 닀륞 것윌로 가알 하는지에 대한 섀명입니닀. 음년 반, 예수 귞늬슀도! 읎믞 얎딘가에 테슀튞와 자료가 있는 PR읎 있을 것입니닀. 읎것을 가능하게 하고, 권장하지 않는 특정 사용 방법읎 있는 겜우 읎륌 위한 tslint가 있습니닀.

this.constructor.staticMember 륌 통핎 Ʞ볞 큎래슀에서 자식 큎래슀의 정적 멀버에 액섞슀할 수 있윌므로 추상 정적 멀버가 읎핎가 됩니닀.

class A {
  f() {
    console.log(this.constructor.x)
  }
}

class B extends A {
  static x = "b"
}

const b = new B
b.f() // logs "b"

큎래슀 A는 f 메서드에서 사용하Ʞ 때묞에 정적 x 멀버가 필요하닀고 지정할 수 있얎알 합니닀.

ì–Žë–€ 소식읎 있습니까?
Ʞ능은 정말 필요합니닀 😄
1) 읞터페읎슀 의 static 핚수
2) 추상 큎래슀 의 abstract static 핚수

정적 읞터페읎슀가 있닀는 아읎디얎는 싫지만 몚든 싀용적읞 목적을 위핎 였늘 은 닀음윌로 충분합니닀.

type MyClass =  (new (text: string) => MyInterface) & { myStaticMethod(): string; }

닀음곌 같읎 사용할 수 있습니닀.

const MyClass: MyClass = class implements MyInterface {
   constructor(text: string) {}
   static myStaticMethod(): string { return ''; }
}

업데읎튞:

아읎디얎 및 싀제 예 에 대한 자섞한 ë‚Žìš©:

// dynamic part
interface MyInterface {
    data: number[];
}
// static part
interface MyStaticInterface {
    myStaticMethod(): string;
}

// type of a class that implements both static and dynamic interfaces
type MyClass = (new (data: number[]) => MyInterface) & MyStaticInterface;

// way to make sure that given class implements both 
// static and dynamic interface
const MyClass: MyClass = class MyClass implements MyInterface {
   constructor(public data: number[]) {}
   static myStaticMethod(): string { return ''; }
}

// works just like a real class
const myInstance = new MyClass([]); // <-- works!
MyClass.myStaticMethod(); // <-- works!

// example of catching errors: bad static part
/*
type 'typeof MyBadClass1' is not assignable to type 'MyClass'.
  Type 'typeof MyBadClass1' is not assignable to type 'MyStaticInterface'.
    Property 'myStaticMethod' is missing in type 'typeof MyBadClass1'.
*/
const MyBadClass1: MyClass = class implements MyInterface {
   constructor(public data: number[]) {}
   static myNewStaticMethod(): string { return ''; }
}

// example of catching errors: bad dynamic part
/*
Type 'typeof MyBadClass2' is not assignable to type 'MyClass'.
  Type 'typeof MyBadClass2' is not assignable to type 'new (data: number[]) => MyInterface'.
    Type 'MyBadClass2' is not assignable to type 'MyInterface'.
      Property 'data' is missing in type 'MyBadClass2'.
*/
const MyBadClass2: MyClass = class implements MyInterface {
   constructor(public values: number[]) {}
   static myStaticMethod(): string { return ''; }
}

@aleksey-bykov 읎것은 Typescript의 잘못읎 아닐 수도 있지만 작동하는 Angular 구성 요소 데윔레읎터와 AoT 컎파음러륌 얻을 수 없습니닀.

@aleksey-bykov 영늬하지만 여전히 추상 정적에서는 작동하지 않습니닀. MyClass 의 하위 큎래슀가 있는 겜우 유형 검사가 적용되지 않습니닀. 제넀늭읎 ꎀ렚된 겜우에도 더 나쁩니닀.

// no errors
class Thing extends MyClass {

}

정적 속성을 요구하는 최종 사용자 띌읎람러늬륌 구축하는 것은 합늬적읞 구현읎 없Ʞ 때묞에 TypeScript 팀읎 읎에 대한 입장을 재고하Ʞ륌 정말로 바랍니닀. 읞터페읎슀 구현자/추상 큎래슀 확장자에 정적 속성읎 있얎알 하는 계앜을 가질 수 있얎알 합니닀.

@bbugh 여Ʞ서 녌의되는 묞제의 졎재 자첎에 의묞을 제Ʞ합니닀. 음반 큎래슀의 읞슀턎슀륌 통핎 동음한 작업을 수행할 수 있닀멎 정적 추상 상속 메서드에 읎러한 몚든 묞제가 필요한 읎유는 묎엇입니까?

class MyAbstractStaticClass {
    abstract static myStaticMethod(): void; // <-- wish we could
}
class MyStaticClass extends MyAbstractStaticClass {
    static myStaticMethod(): void {
         console.log('hi');
    }
}
MyStaticClass.myStaticMethod(); // <-- would be great

대

class MyAbstractNonStaticClass {
    abstract myAbstractNonStaticMethod(): void;
}
class MyNonStaticClass extends MyAbstractNonStaticClass {
    myNonStaticMethod(): void {
        console.log('hi again');
    }
}
new MyNonStaticClass().myNonStaticMethod(); // <-- works today

@aleksey-bykov 많은 읎유가 있습니닀. 예륌 듀얎(@patryk-zielinski93 에서 ):

abstract class Serializable {  
    abstract serialize (): Object;  
    abstract static deserialize (Object): Serializable;  
}  

Serializable의 하위 큎래슀에서 정적 역직렬화 메서드륌 강제로 구현하고 싶습니닀.
귞러한 동작을 구현하Ʞ 위한 í•Žê²° 방법읎 있습니까?

펞집: deserialize 륌 생성자로 사용할 수도 있닀는 것을 알고 있지만 큎래슀에는 팩토늬 메서드가 필요한 생성자가 1개만 있을 수 있습니닀. 사람듀은 읞터페읎슀에서 팩토늬 메소드륌 요구하는 방법을 원하는데, 읎는 완전히 의믞가 있습니닀.

역직렬화되는 바로 ê·ž 큎래슀에 정적 역직렬화 메소드륌 첚부하는 읎점읎 없Ʞ 때묞에 닚순히 욕구화 녌늬륌 별도의 큎래슀로 가젞갑니닀.

class Deserializer {
     deserializeThis(...): Xxx {}
     deserializeThat(...): Yyy {}
}

묎엇읎 묞제읞가?

@aleksey-bykov 별도의 큎래슀가 예쁘지 않습니닀.

@aleksey-bykov, 묞제는 직렬화가 필요한 큎래슀가 2개 읎상 있닀는 것입니닀. 따띌서 귀하의 ì ‘ê·Œ 방식은 uberclass 반팚턎읞 직렬화 사전을 만드는 방향윌로 강제되고 있윌며 읎듀 쀑 하나륌 수정할 때마닀 읎 uberclass에서 펞집읎 필요합니닀. 윔드 지원을 귀찮게 만듭니닀. 직렬화 가능한 읞터페읎슀가 있윌멎 죌얎진 객첎 유형에 대한 구현을 강제할 수 있지만 사람듀읎 원하는 죌요 읎유읞 닀형성 상속도 지원합니닀. 혜택읎 있는지 없는지 추잡하지 마십시였. 누구나 선택권읎 있고 자신의 프로젝튞에 유익한 것을 선택할 수 있얎알 합니닀.

@octaharon 은 역직렬화 전용 큎래슀륌 갖는 것은 당신읎 말한 것곌 정반대읎며, 역직렬화에 대핮 신겜을 ì“ž 때만 변겜하Ʞ 때묞에 닚음 책임읎 있습니닀.

반대로 당신읎 제안한 것처럌 큎래슀 자첎에 역직렬화륌 추가하멎 추가 책임곌 변겜 읎유가 추가됩니닀.

마지막윌로 정적 메서드에는 묞제가 없지만 추상 정적 메서드 및 정적 읞터페읎슀에 대한 싀제 사용 사례륌 볎고 싶얎 정말 궁ꞈ합니닀.

@octaharon 은 역직렬화 전용 큎래슀륌 갖는 것은 당신읎 말한 것곌 정반대읎며, 역직렬화에 대핮 신겜을 ì“ž 때만 변겜하Ʞ 때묞에 닚음 책임읎 있습니닀.

(비)직렬화는 유형 구조에 따띌 닀륎므로 한 곳읎 아닌 두 곳에서 윔드륌 변겜핎알 한닀는 점을 제왞하고. 읎는 "닚음 책임"에 포핚되지 않습니닀.

반대로 당신읎 제안한 것처럌 큎래슀 자첎에 역직렬화륌 추가하멎 추가 책임곌 변겜 읎유가 추가됩니닀.

나는 당신읎 말하는 것을 읎핎하지 못합니닀. 자첎 (역)직렬화륌 닎당하는 큎래슀가 정확히 ë‚Žê°€ 원하는 것읎므로 옳고 귞늄을 말하지 마십시였.

닚음 책임은 ꎀ렚된 파음 수에 대핮 아묎 것도 말하지 않고 닚음 읎유만 있얎알 한닀고 말합니닀.

ë‚Žê°€ 말하렀는 것은 새 큎래슀륌 추가할 때 닚순히 역직렬화되는 것읎 아닌 닀륞 것을 의믞하므로 읎믞 졎재하는 읎유와 귞에 할당된 책임읎 있닀는 것입니닀. 귞런 닀음 자첎륌 역직렬화할 수 있는 또 닀륞 책임을 추가합니닀. 읎것은 우늬에게 2가지 책임을 부여합니닀. 읎것은 SOLID륌 위반합니닀. 렌더링, 읞쇄, 복사, 전송, 암혞화 등곌 같은 더 많은 것을 계속 추가하멎 신 큎래슀륌 얻게 됩니닀.

진부한 말을 í•Žì„œ 죄송합니닀. 하지만 읎점곌 싀제 사용 사례에 대한 질묞(및 답변)읎 읎 Ʞ능 제안을 구현하게 만드는 원동력입니닀.

SOLID는 전능하신 하나님께서 태랔늿윌로 볎낎신 것읎 아니며, 있닀고 하더띌도 핎석의 자유도가 있습니닀. 당신은 당신읎 귞것에 대핮 원하는 만큌 읎상죌의적음 수 있지만, 제게 부탁을 듀얎 죌십시였. 당신의 믿음을 지역 사회에 퍌뜚늬지 마십시였. 몚든 사람은 원하는 방식윌로 몚든 도구륌 사용하고 ê·žê°€ 알고 있는 몚든 가능한 규칙을 위반할 수 있는 몚든 권늬가 있습니닀(삎읞에 대핮 칌을 비난할 수는 없습니닀). 도구의 품질을 정의하는 것은 특정 Ʞ능에 대한 수요와 귞에 대한 제안 간의 균형입니닀. 귞늬고 읎 분Ʞ는 수요량을 볎여쀍니닀. 읎 Ʞ능읎 필요하지 않닀멎 사용하지 마십시였. 귞렇닀. 귞늬고 여Ʞ 있는 많은 사람듀도 귞것을 필요로 하고 _우늬는_ 싀용적읞 사용 사례륌 가지고 있지만 싀제로는 우늬가 귞것을 묎시핎알 한닀고 말하고 있습니닀. 귞것은 유지자듀에게 더 쀑요한 것, 슉 신성한 원칙(귞듀읎 읎핎하는 방식에 상ꎀ없읎) 또는 컀뮀니티에 ꎀ한 것입니닀.

ì–Žë–€ 좋은 제안은 사용 사례륌 제공하지만 읎 제안은

image

귞래서 나는 닚지 앜간의 혞Ʞ심을 표현하고 질묞을 했습니닀. 제안서에는 귞것을 말하지 ì•Šêž° 때묞에, 왜 사람듀읎 귞것을 필요로 하는지

귞것은 전형적읞 것윌로 요앜됩니닀. 정당한 읎유, 감히하지 마십시였

개읞적윌로 나는 solid 또는 oop에 대핮 신겜 쓰지 않습니닀. 나는 였래전에 우연히 귞것을 곌도하게 성장시쌰습니닀. 당신은 "uberclass antipattern" 녌쟁을 던지고 나서 귞것을 "핎석에 대한 자유도"로 뒷받칚했습니닀.

읎 전첎 토론에서 얞꞉된 유음한 싀질적읞 읎유는 닀음곌 같습니닀. https://github.com/Microsoft/TypeScript/issues/14600#issuecomment -308362119

읎것읎 도움읎 될 맀우 음반적읞 사용 사례는 displayName, propTypes 및 defaultProps와 같은 정적 속성읎 있는 큎래슀읞 React 구성 요소입니닀.

및 몇 가지 게시묌 유사 https://github.com/Microsoft/TypeScript/issues/14600#issuecomment -345496014

하지만 (new (...) => MyClass) & MyStaticInterface 로 덮여 있습니닀.

귞것읎 정확한 사용 사례읎자 ë‚Žê°€ 여Ʞ에 있는 읎유입니닀. 투표수 볎읎시나요? 묎엇읎 practical 읎고 묎엇읎 아닌지 결정하는 것읎 왜 개읞적윌로 귀하에게 달렀 있닀고 생각합니까? Practical 는 practice 에 넣을 수 있는 것입니닀. (Ꞁ을 쓰는 시점에서) 83명읎 읎 Ʞ능읎 정말 싀용적읎띌고 생각할 것입니닀. 닀륞 사람듀을 졎쀑하고 묞맥에서 묞구륌 꺌낎고 닀양한 유행얎륌 볎여죌Ʞ 전에 전첎 슀레드륌 읜윌십시였. 당신읎 극복한 것읎 묎엇읎든, 귞것은 확싀히 당신의 에고가 아닙니닀.

싀용적읞 것은 묞제륌 핎결하는 것읎고, 비싀용적읞 것은 당신의 믞감을 자극하는 것읎띌는 것은 상식입니닀. 저는 닀륞 사람듀을 졎쀑합니닀. https://github.com/Microsoft/TypeScript/issues/14600#issuecomment -308362119 및 https://github.com/Microsoft/TypeScript/issues/14600#issuecomment -289084844에 대핮 죌얎진 (new (...) => MyClass) & MyStaticInterface 륌 핎결하십시였.

대답하지 말아죌섞요

같은 읎유로 나는 때때로 큰 죌석을 쀄읎Ʞ 위핎 type 선얞을 사용합니닀 abstract static 와 같은 킀워드는 Ʞ졎에 얞꞉된 것처럌 상대적윌로 소화하Ʞ 얎렀욎 구묞볎닀 훚씬 읜Ʞ 쉜습니닀. 예시.

게닀가 아직 추상 큎래슀륌 닀룚지 않았습니까?

낮 생각에는 추상 큎래슀륌 사용하지 않는 솔룚션읎 솔룚션읎 아닙니닀. 귞것은 í•Žê²° 방법입니닀! í•Žê²° 방법은 묎엇입니까?

읎 Ʞ능 요청은 요청자륌 포핚한 많은 사람듀읎 읞터페읎슀에 abstract static 또는 static 와 같은 예상 Ʞ능읎 졎재하지 않는닀는 것을 발견했Ʞ 때묞에 졎재한닀고 생각합니닀.

제공된 솔룚션에 따띌 static 킀워드가 사용되지 않도록 하는 í•Žê²° 방법읎 있는 겜우에도 졎재핎알 합니까? 제안하는 것도 마찬가지로 얎늬석은 음읎띌고 생각합니닀.

여Ʞ서 묞제는 static 가 훚씬 더 합늬적읎띌는 것입니닀.
생성된 ꎀ심을 바탕윌로 덜 묎시하는 토론을 할 수 있습니까?

읎 제안에 대한 업데읎튞가 있습니까? static abstract 등읎 없얎알 하는 읎유륌 섀명할 가치가 있는 읞수가 있습니까?
왜 귞것읎 유용한지 볎여죌는 제안읎 더 있을 수 있습니까?

아마도 우늬는 묞제륌 정늬하고 녌의된 낎용을 요앜하여 핎결책을 ì°Ÿì•„ì•Œ 할 것입니닀.

ë‚Žê°€ 읎핎하는 두 가지 제안읎 있습니닀.

  1. 읞터페읎슀와 유형은 정적 속성곌 메서드륌 정의할 수 있습니닀.
interface ISerializable<T> { 
   static fromJson(json: string): T;
}
  1. 추상 큎래슀는 추상 정적 메서드륌 정의할 수 있습니닀.
abstract class MyClass<T> implements ISerializable<T> {
   abstract static fromJson(json: string): T;
}

class MyOtherClass extends MyClass<any> {
  static fromJson(json: string) {
  // unique implementation
  }
}

제안 1에 ꎀ핎서는 Ʞ술적윌로 í•Žê²° 방법읎 있습니닀! 대당한 것은 아니지만 최소한 ê·ž 정도는 됩니닀. 귞러나 귞것은 í•Žê²° 방법입니닀.

읞터페읎슀륌 둘로 나누고 닀음곌 같읎 큎래슀륌 닀시 작성할 수 있습니닀.

interface StaticInterface {
  new(...args) => MyClass;
  fromJson(json): MyClass;
}

interface InstanceInterface {
  toJson(): string;
}

const MyClass: StaticInterface = class implements InstanceInterface {
   ...
}

낮 생각에 읎것은 많은 추가 작업곌 앜간 덜 가독성읎 있윌며 닚순히 읎상하고 우늬가 사용하는 구묞에서 벗얎나는 재믞있는 방식윌로 큎래슀륌 닀시 작성하는 닚점읎 있습니닀.

귞러나 제안 2는 얎떻습니까? 귞것에 대핮 할 수 있는 음은 아묎것도 없잖아요? 귞것도 닀룰 가치가 있닀고 생각합니닀!

읎러한 유형 쀑 하나의 싀제 용도는 묎엇입니까? 읎 유형 쀑 하나는 얎떻게 사용됩니까?

interface JsonSerializable {
    toJSON(): string;
    static fromJSON(serializedValue: string): JsonSerializable;
}

값은 { fromJSON(serializedValue: string): JsonSerializable; } 와 같은 객첎여알 한닀고 읎믞 말할 수 있습니닀. 귞래서 읎것은 닚지 팚턎을 적용하Ʞ 위핎 원하는 것입니까? 나는 유형 검사 ꎀ점에서 읎점을 볎지 못합니닀. ì°žê³ ë¡œ 읎 겜우 작업하Ʞ 얎렀욎 팚턎읎 적용됩니닀. 여Ʞ서 닀룚지 않을 여러 가지 읎유로 직렬화 프로섞슀륌 별도의 직렬 변환Ʞ 큎래슀 또는 핚수로 읎동하는 것읎 좋습니닀.

게닀가 왜 읎런 음읎 음얎나고 있습니까?

class FirstChildClass extends AbstractParentClass {
    public static getSomeClassDependentValue(): string {
        return 'Some class-dependent value of class FirstChildClass';
    }
}

대신 템플늿 방법읎나 전략 팚턎을 사용하는 것은 얎떻습니까? 귞렇게 하멎 더 유연하게 작동할 것입니닀. 맞죠?

현재로서는 작업하Ʞ 힘든 큎래슀 디자읞을 섀명하Ʞ 위핎 불필요한 복잡성을 추가하는 것처럌 볎읎Ʞ 때묞에 읎 Ʞ능에 반대합니닀. ë‚Žê°€ 놓치고 있는 읎점읎 있을 수 있습니까?

정적 React 메서드에 대한 유횚한 사용 사례가 하나 있습니닀.

@aleksey-bykov 아, 알겠습니닀. 읎러한 겜우 constructor 속성에 유형을 추가하멎 드묞 시나늬였에서 유형 검사가 발생하는 것읎 더 나을 수 있습니닀. 예륌 듀얎:

interface Component {
    constructor: ComponentConstructor;
}

interface ComponentConstructor {
    displayName?: string;
}

class MyComponent implements Component {
    static displayName = 5; // error
}

귞것읎 나에게 훚씬 더 가치가 있는 것 같닀. 귞것은 얞얎에 추가적읞 복잡성을 추가하지 않윌며 큎래슀가 읞터페읎슀륌 올바륎게 구현하는지 확읞할 때 유형 검사Ʞ에 더 많은 작업을 추가할 뿐입니닀.


귞걎 귞렇고, 유횚한 사용 사례는 읞슀턎슀에서 생성자로 읎동하고 마지막윌로 유형 검사가 있는 정적 메서드 또는 속성윌로 읎동할 때띌고 생각했지만 유형에 constructor 속성을 입력하멎 읎믞 가능합니닀. #3841의 큎래슀 읞슀턎슀에 대핮 핎결됩니닀.

나는 비슷한 생각을 가지고 있었닀 : https://github.com/Microsoft/TypeScript/issues/14600#issuecomment -437071092

업슀레드에 섀명된 직렬화/역직렬화 팚턎읎 "유횚"하지 않습니까?

@dsherret 은 "유형 검사 ꎀ점에서 읎점을 볎지 못합니닀". 뚌저 정적 분석을 수행하는 요점은 가능한 한 빚늬 였류륌 포착하는 것입니닀. 혞출 서명을 변겜핎알 하는 겜우 혞출하는 몚든 사람, 또는 결정적윌로 서명을 사용하는 메서드 구현을 닎당하는 몚든 사람읎 새 서명윌로 업데읎튞하도록 입력합니닀.

정적 foo(x: number, y: boolean, z: string) 메서드가 있는 형제 큎래슀 섞튞륌 제공하는 띌읎람러늬가 있고 사용자가 읎러한 큎래슀 쀑 여러 개륌 사용하고 읞슀턎슀륌 생성하Ʞ 위핎 메서드륌 혞출하는 팩토늬 큎래슀륌 작성할 것윌로 예상한닀고 가정합니닀. (아마도 deserialize 또는 clone 또는 unpack 또는 loadFromServer , 쀑요하지 않습니닀.) 사용자는 또한 동음한(추상적음 수 있는) 부몚의 하위 큎래슀륌 만듭니닀. 도서ꎀ에서 수업.

읎제 마지막 맀개변수가 옵션 객첎가 되도록 핎당 계앜을 변겜핎알 합니닀. ì„ž 번짞 읞수에 대한 묞자엎 값을 전달하는 것은 컎파음 타임에 플래귞륌 지정핎알 하는 복구할 수 없는 였류입니닀. foo 륌 혞출할 때 대신 객첎륌 전달하도록 몚든 팩토늬 큎래슀륌 업데읎튞핎알 하며 foo 륌 구현하는 하위 큎래슀는 혞출 서명을 변겜핎알 합니닀.

새 띌읎람러늬 버전윌로 업데읎튞하는 사용자가 컎파음 타임에 죌요 변겜 사항을 포착할 수 있도록 볎장하고 싶습니닀. 띌읎람러늬는 위의 정적 읞터페읎슀 í•Žê²° 방법 쀑 하나(예 type MyClass = (new (data: number[]) => MyInterface) & MyStaticInterface; )륌 낎볎낎고 소비자가 올바륞 위치에 적용하Ʞ륌 바랍니닀. 구현 쀑 하나륌 장식하는 것을 잊었거나 팩토늬 큎래슀에서 foo 의 혞출 서명을 섀명하Ʞ 위핎 띌읎람러늬 낎볎낞 유형을 사용하지 않은 겜우 컎파음러는 변겜된 사항을 알 수 없윌며 런타임 였류가 발생합니닀. . 부몚 큎래슀에서 abstract static 메서드륌 합늬적윌로 구현하는 것곌 대조적윌로 -- 특별한 죌석읎 필요하지 않고 소비 윔드에 대한 부닎읎 없윌며 슉시 작동합니닀.

@thw0rted 대부분의 띌읎람러늬는 읎러한 큎래슀의 등록을 요구하지 않윌며 ê·ž 시점에서 유형 검사가 발생할 수 있습니까? 예륌 듀얎:

// in the library code...
class SomeLibraryContext {
    register(classCtor: Function & { deserialize(serializedString: string): Component; }) {
        // etc...
    }
}

// then in the user's code
class MyComponent extends Comonent {
    static deserialize(serializedString: string) {
        return JSON.parse(serializedString) as Component;
    }
}

const context = new SomeLibraryContext();
// type checking occurs here today. This ensures `MyComponent` has a static deserialize method
context.register(MyComponent);

아니멎 읎러한 큎래슀의 읞슀턎슀가 띌읎람러늬와 핚께 사용되고 띌읎람러늬가 정적 메서드륌 가젞였Ʞ 위핎 읞슀턎슀에서 생성자로 읎동합니까? 귞렇닀멎 정적 메서드가 필요하지 않도록 띌읎람러늬 디자읞을 변겜할 수 있습니닀.

ì°žê³ ë¡œ 읞터페읎슀의 구현자로서 생성자가 없Ʞ 때묞에 정적 메서드에 종속성을 죌입하Ʞ가 맀우 얎렵Ʞ 때묞에 정적 메서드륌 작성핎알 하는 겜우 맀우 짜슝읎 날 것입니닀(ctor 종속성은 가능하지 않음). 또한 상황에 따띌 역직렬화 구현을 닀륞 것윌로 바꟞는 것도 얎렵게 만듭니닀. 예륌 듀얎 닀륞 직렬화 메컀니슘을 사용하여 닀륞 소슀에서 역직렬화하고 있닀고 가정핎 볎겠습니닀. 읎제 정적 역직렬화 메서드가 있습니닀. 읎 메서드는 섀계상 큎래슀 구현에 대핮 한 가지 방법윌로만 구현할 수 있습니닀. 읎 묞제륌 핎결하렀멎 정적 역직렬화 메서드에 사용할 항목을 알렀죌는 닀륞 전역 정적 속성읎나 메서드가 큎래슀에 있얎알 합니닀. 사용할 항목을 쉜게 바꿀 수 있고 (역)직렬화되는 큎래슀에 (역)직렬화륌 연결하지 않는 별도의 Serializer 읞터페읎슀륌 선혞합니닀.

묎슚 말읞지 알겠습니닀. 팩토늬 팚턎을 사용하렀멎 ê²°êµ­ 구현 큎래슀륌 팩토늬에 전달핎알 하며 읎때 정적 검사가 발생합니닀. 나는 여전히 공장 혾환 큎래슀륌 제공하고 싶지만 지ꞈ은 싀제로 사용하지 않는 겜우가 있을 수 있닀고 생각합니닀. 읎 겜우 abstract static 제앜 조걎읎 묞제륌 더 음찍 포착하고 의믞륌 더 명확하게 만듭니닀.

나는 당신의 "sidenote" ꎀ심사에 얎Ꞌ나지 않는닀고 생각하는 또 닀륞 예가 있습니닀. 나는 사용자에게 특정 Ʞ능에 사용할 "제공자"륌 선택하도록 하는 프론튞엔드 프로젝튞에 여러 형제 큎래슀가 있습니닀. 묌론 name => Provider 얎딘가에 사전을 만듀고 킀륌 사용하여 선택 목록에 표시할 낎용을 결정할 수 있지만 지ꞈ 구현한 방법은 정적 name 필드륌 요구하는 것입니닀. 각 공꞉자 구현에서.

얎느 시점에서 shortName 및 longName (사용 가능한 화멎 공간의 양읎 서로 닀륞 컚텍슀튞에서 표시하Ʞ 위핎)륌 몚두 요구하도록 변겜했습니닀. $#$ providerList: Type<Provider> & { shortName: string } & { longName: string } 륌 가지도록 선택 목록 구성 요소륌 변겜하는 대신 abstract static name: string; 륌 abstract static shortName: string; 등윌로 변겜하는 것읎 훚씬 더 간닚했을 것입니닀. 의도륌 올바륞 위치 (슉, 소비 구성 요소가 아닌 추상 부몚)에 전달하고 읜Ʞ 쉜고 변겜하Ʞ 쉜습니닀. í•Žê²° 방법읎 있닀고 말할 수 있닀고 생각하지만 여전히 제안된 변겜 사항볎닀 객ꎀ적윌로 더 나쁘닀고 생각합니닀.

최귌에 읞터페읎슀에서 정적 메서드륌 사용핎알 할 때 읎 묞제륌 발견했습니닀. 읎 많은 댓Ꞁ을 읜을 시간읎 없Ʞ 때묞에 읎 묞제가 읎전에 읎믞 핎결된 겜우 사곌드늜니닀.

낮 현재 묞제: 낮 TypeScript 프로젝튞에서 사용하렀는 개읞 .js 띌읎람러늬가 있습니닀. 귞래서 계속핎서 핎당 띌읎람러늬에 대한 .d.ts 파음을 작성하Ʞ 시작했지만 띌읎람러늬가 정적 메서드륌 사용하Ʞ 때묞에 싀제로 완료할 수 없었습니닀. 읎 겜우 제안된 ì ‘ê·Œ 방식은 묎엇입니까?

답변 감사합니닀.

@greeny 는 작동하는 솔룚션입니닀. https://github.com/Microsoft/TypeScript/issues/14600#issuecomment -437071092

특히 읎 부분:

type MyClass = (new (text: string) => MyInterface) & { myStaticMethod(): string; }

또 닀륞 사용 사례: 생성된 윔드/부분 큎래슀 shim

  • 나는 swagger 사양을 생성하는 @rsuter/nswag 띌읎람러늬륌 사용하고 있습니닀.
  • 생성된 파음에 병합되는 '확장' 파음을 작성할 수 있습니닀.
  • 확장 파음은 싀행되지 않지만 자첎적윌로 컎파음핎알 합니닀!
  • 때때로 ê·ž 파음 낎에서 아직 졎재하지 않는 것을 ì°žì¡°í•Žì•Œ 합니닀(생성되Ʞ 때묞에)
  • 따띌서 닀음곌 같읎 shim/읞터페읎슀륌 선얞하고 싶습니닀.
  • ì°žê³ : 최종 병합에서 특정 import 묞읎 묎시되도록 지정할 수 있윌므로 최종 생성 윔드에서 'shim' 포핚읎 묎시됩니닀.
interface SwaggerException
{
    static isSwaggerException(obj: any): obj is SwaggerException;
}

귞러나 나는 읎것을 할 수 없윌며 싀제로 큎래슀륌 작성핎알 합니닀. 읎것은 ꎜ찮지만 여전히 잘못된 느낌입니닀. 나는 닚지 - 닀륞 많은 사람듀읎 말했듯읎 - '읎것읎 계앜읎닀'띌고 말하고 싶습니닀.

윔드 생성에 대한 닀륞 얞꞉을 볌 수 없Ʞ 때묞에 여Ʞ에 추가하고 싶었습니닀. 하지만 많은 '읎것읎 필요한 읎유' 죌석은 ​​짜슝을 유발합니닀. 읞터페읎슀에서 읎 '정적' Ʞ능을 '필요로 하는' 상당한 비윚의 사람듀읎 왞부 띌읎람러늬 항목을 ì°žì¡°í•  수 있도록 핎당 Ʞ능을 수행할 것윌로 예상합니닀.

또한 더 깚끗한 d.ts 파음을 볎고 싶습니닀. 읎 Ʞ능곌 핎당 파음곌 겹치는 부분읎 있얎알 합니닀. JQueryStatic 같은 것은 귞냥 핎킹처럌 볎읎Ʞ 때묞에 읎핎하Ʞ 얎렵습니닀. 또한 현싀은 d.ts 파음읎 종종 였래 되고 유지 ꎀ늬되지 않윌며 shim을 직접 ì„ ì–ží•Žì•Œ 합니닀.

(jQuery륌 얞꞉핎서 죄송합니닀)

직렬화의 겜우 나는 귞런 음을했습니닀.

export abstract class World {

    protected constructor(json?: object) {
        if (json) {
            this.parseJson(json);
        }
    }

    /**
     * Apply data from a plain object to world. For example from a network request.
     * <strong i="6">@param</strong> json Parsed json object
     */
    abstract parseJson(json: object): void;

    /**
     * Parse instance to plane object. For example to send it through network.
     */
    abstract toJson(): object;
}

귞러나 닀음곌 같은 것을 사용하는 것읎 훚씬 더 쉬욞 것입니닀.

export abstract class World {

    /**
     * Create a world from plain object. For example from a network request.
     * <strong i="10">@param</strong> json Parsed json object
     */
    abstract static fromJson(json: object): World;

    /**
     * Parse instance to plane object. For example to send it through network.
     */
    abstract toJson(): object;
}

나는 읎 쓰레드륌 많읎 적었지만 나는 여전히 왜 읎 팚턎에 대핮 아니였띌고 말하는 것읎 좋고 올바륞지 읎핎하지 못합니닀. 당신읎 ê·ž 의견을 공유한닀멎, 당신은 또한 자바와 닀륞 읞Ʞ 있는 얞얎듀읎 귞것을 잘못 만든닀고 말합니닀. 아니멎 ë‚Žê°€ 틀렞습니까?

읎 묞제는 2년 동안 공개되었윌며 79개의 댓Ꞁ읎 있습니닀. Awaiting More Feedback 로 레읎랔읎 지정됩니닀. 결정을 낎늬Ʞ 위핎 ì–Žë–€ 플드백읎 더 필요한지 말씀핎 죌시겠습니까?

읞터페읎슀나 추상 큎래슀(선얞만 핎당)에서 정적 메서드륌 섀명할 수 없닀는 것은 정말 짜슝나는 음입니닀. 읎 Ʞ능읎 아직 구현되지 않았Ʞ 때묞에 í•Žê²° 방법을 작성하는 것은 너묎 추악합니닀 =(

예륌 듀얎 next.js는 페읎지륌 구성하Ʞ 전에 페읎지 속성을 가젞였Ʞ 위핎 정적 getInitialProps 핚수륌 사용합니닀. throw되는 겜우 페읎지가 생성되지 않고 였류 페읎지가 생성됩니닀.

https://github.com/zeit/next.js/blob/master/packages/next/README.md#fetching -data-and-component-lifecycle

귞러나 불행하게도, 읎 메소드륌 구현하는 ë‹šì„œ ts는 유형 검사가 불가능하Ʞ 때묞에 런타임에 였류가 발생하더띌도 몚든 유형 서명을 제공할 수 있습니닀.

자바슀크늜튞 자첎가 정적읞 걞 잘 못핎서 읎 묞제가 여Ʞ 였래 졎재하는 것 같아요 🀔

정적 상속은 애쎈에 졎재핎서는 안 됩니닀. 🀔🀔

누가 정적 메서드륌 혞출하거나 정적 필드륌 읜고 싶습니까? 🀔🀔🀔

  • 자식 큎래슀: 정적읎 아니얎알 합니닀.
  • 부몚 큎래슀: 생성자 읞수 사용
  • Ʞ타: ISomeClassConstructor 읞터페읎슀 사용

닀륞 사용 사례가 있습니까?🀔🀔🀔🀔

읎것에 대한 업데읎튞가 있습니까?

도움읎 된닀멎 큎래슀의 정적 읞터페읎슀륌 입력핎알 하는 겜우에 수행한 작업은 데윔레읎터륌 사용하여 큎래슀의 정적 멀버륌 적용하는 것입니닀.

데윔레읎터는 닀음곌 같읎 정의됩니닀.

export const statics = <T extends new (...args: Array<unknown>) => void>(): ((c: T) => void) => (_ctor: T): void => {};

닀음곌 같읎 정의된 정적 생성자 멀버 읞터페읎슀가 있는 겜우

interface MyStaticType {
  new (urn: string): MyAbstractClass;
  isMember: boolean;
}

T의 멀버륌 닀음곌 같읎 정적윌로 ì„ ì–ží•Žì•Œ 하는 큎래슀에서 혞출됩니닀.

@statics<MyStaticType>()
class MyClassWithStaticMembers extends MyAbstractClass {
  static isMember: boolean = true;
  // ...
}

가장 빈번한 예는 닀음곌 같습니닀.

interface JsonSerializable {
    toJSON(): string;
    static fromJSON(serializedValue: string): JsonSerializable;
}

귞러나 여Ʞ #13462에서 말했듯읎 :

읞터페읎슀는 개첎가 제공하는 Ʞ능을 정의핎알 합니닀. 읎 Ʞ능은 재정의 가능하고 상혞 교환 가능핎알 합니닀(읎것읎 읞터페읎슀 메소드가 가상읞 읎유입니닀). 정적은 동적 동작/가상 방법곌 유사한 개념입니닀.

TypeScript에서 읞터페읎슀는 개첎 읞슀턎슀 자첎와 사용 방법을 섀명한닀는 점에 동의합니닀. 묞제는 개첎 읞슀턎슀가 큎래슀 정의가 아니며 static Ʞ혞가 큎래슀 정의에만 졎재할 수 있닀는 것입니닀.

귞래서 나는 몚든 결점곌 핚께 닀음을 제안할 수 있습니닀.


읞터페읎슀는 개첎 또는 큎래슀 륌 섀명할 수 있습니닀. 큎래슀 읞터페읎슀가 class_interface 킀워드로 표시된닀고 가정핎 볎겠습니닀.

class_interface ISerDes {
    serialize(): string;
    static deserialize(str: string): ISerDes
}

큎래슀(및 큎래슀 읞터페읎슀)는 statically implements 킀워드륌 사용하여 개첎 읞터페읎슀륌 사용하여 정적 Ʞ혞륌 ì„ ì–ží•  수 있습니닀( 큎래슀 읞터페읎슀는 statically 구현될 수 없음).

큎래슀(및 큎래슀 읞터페읎슀)는 여전히 개첎 읞터페읎슀 또는 큎래슀 읞터페읎슀와 핚께 implements 킀워드륌 사용합니닀.

큎래슀 읞터페읎슀는 정적윌로 구현된 객첎 읞터페읎슀와 읞슀턎슀 구현 읞터페읎슀륌 혌합할 수 있습니닀. 따띌서 닀음을 얻을 수 있습니닀.

interface ISerializable{
    serialize(): string;
}
interface IDeserializable{
    deserialize(str: string): ISerializable
}

class_interface ISerDes implements ISerializable statically implements IDeserializable {}

읎런 식윌로 읞터페읎슀는 의믞륌 유지할 수 있고 class_interface 는 큎래슀 정의 전용의 새로욎 종류의 추상화 Ʞ혞가 됩니닀.

쀑요하지 않은 작은 사용 사례 하나 더:
Angular for AOT 컎파음에서는 데윔레읎터에서 핚수륌 혞출할 수 없습니닀(예: @NgModule 몚듈 데윔레읎터).
각도 묞제

서비슀 작업자 몚듈의 겜우 닀음곌 같은 것읎 필요합니닀.
ServiceWorkerModule.register('ngsw-worker.js', {enabled: environment.production})
Ʞ볞 값곌 구현할 추상 속성윌로 추상 큎래슀륌 확장하는 하위 큎래슀륌 사용하는 환겜입니닀. 유사한 구현 예
따띌서 큎래슀 생성읎 핚수읎고 닀음곌 같은 였류가 발생하Ʞ 때묞에 AOT가 작동하지 않습니닀. Function calls are not supported in decorators but ..

작동하게 하고 자동 완성/컎파음러 지원을 유지하렀멎 정적 수쀀에서 동음한 속성을 정의할 수 있습니닀. 귞러나 '구현' 속성을 위핎서는 추상 큎래슀의 정적 멀버 또는 추상 정적 멀버와의 읞터페읎슀가 필요합니닀. 둘 ë‹€ 아직 불가능합니닀.

읞터페읎슀륌 사용하멎 닀음곌 같읎 작동할 수 있습니닀.

// default.env.ts
interface ImplementThis {
  static propToImplement: boolean;
}

class DefaultEnv {
  public static production: boolean = false;
}

// my.env.ts
class Env extends DefaultEnv implements ImplementThis {
  public static propToImplement: true;
}

export const environment = Env;

추상 정적을 사용하멎 닀음곌 같읎 작동할 수 있습니닀.

// default.env.ts
export abstract class AbstractDefaultEnv {
  public static production: boolean = false;
  public abstract static propToImplement: boolean;
}
// my.env.ts
class Env extends AbstractDefaultEnv {
  public static propToImplement: true;
}

export const environment = Env;

í•Žê²° 방법 읎 있지만 몚두 앜합니닀./

@DanielRosenwasser @RyanCavanaugh 는 얞꞉에 대핮 사곌하지만 컀뮀니티의 많은 지원을 받고 있고 구현하Ʞ가 상당히 쉬욞 것읎띌고 생각하는 읎 Ʞ능 제안읎 묞제 범죌에 깊숙읎 묻힌 것 같습니닀. 읎 Ʞ능에 대한 의견읎 있윌신가요? PR을 환영합니까?

읎 묞제는 #1263의 복제볞읎 아닙니까? 😛

26398(구현 유형의 생성자 속성을 Ʞ반윌로 하는 유형 검사 정적 멀버)가 더 나은 솔룚션처럌 볎입니닀... 읎와 같은 것읎 구현된닀멎 귞것읎 바로 귞것음 것입니닀. 추가 구묞/파싱읎 필요하지 않윌며 닚음 시나늬였에 대한 유형 검사 변겜음 뿐입니닀. 또한 읎것만큌 많은 질묞을 제Ʞ하지 않습니닀.

읞터페읎슀의 정적 메서드는 추상 큎래슀에 정적 추상 메서드륌 사용하는 것만큌 직ꎀ적읎지 않은 것 같습니닀.

읞터페읎슀는 큎래슀가 아닌 객첎륌 정의핎알 하Ʞ 때묞에 읞터페읎슀에 정적 메서드륌 추가하는 것은 앜간 슀쌀치적읎띌고 생각합니닀. 반멎에 추상 큎래슀는 하위 큎래슀륌 정의하는 데 사용되므로 추상 큎래슀에는 정적 추상 메서드가 있얎알 합니닀. 읎 구현읎 진행되는 한, 추상 큎래슀륌 확장할 때(예: class extends MyAbstractClass ), 유형윌로 사용할 때(예: let myInstance: MyAbstractClass )가 아니띌 유형 검사만 하멎 됩니닀.

예시:

abstract class MyAbstractClass {
  static abstract bar(): number;
}

class Foo extends MyAbstractClass {
  static bar() {
    return 42;
  }
}

지ꞈ은 부득읎하게 읎것을 사용합니닀

abstract class MultiWalletInterface {

  static getInstance() {} // can't write a return type MultiWalletInterface

  static deleteInstance() {}

  /**
   * Returns new random  12 words mnemonic seed phrase
   */
  static generateMnemonic(): string {
    return generateMnemonic();
  }
}

읎것은 불펞하닀!

"개첎"에 속성을 추가하는 묞제가 발생했습니닀. 여Ʞ에 샌드박슀 예제 가 있습니닀.

interface Object {
    getInstanceId: (object: any) => number;
}

Object.getInstanceId = () => 42;
const someObject = {};
Object.getInstanceId(someObject); // correct
someObject.getInstanceId({}); // should raise an error but does not

읎제 몚든 개첎 읞슀턎슀에는 getInstanceId 속성읎 있는 것윌로 간죌되지만 Object 있얎알 합니닀. 정적 속성읎 있윌멎 묞제가 핎결되었을 것입니닀.

Object가 아닌 ObjectConstructor륌 볎강하고 싶습니닀. 싀제로 생성자 자첎에 메서드륌 연결하렀는 겜우 읞슀턎슀 메서드륌 선얞합니닀. ì„ ì–ž 병합을 통핎 읎것읎 읎믞 가능하닀고 생각합니닀.

````
전역 ì„ ì–ž {
읞터페읎슀 객첎 생성자 {
안녕하섞요(): 묞자엎;
}
}

Object.hello();
````

@thw0rted 훌륭합니닀! ObjectConstructor륌 몰랐습니닀 감사합니닀

더 큰 요점은 읞슀턎슀 유형읎 아닌 생성자 유형을 볎강하고 있닀는 것입니닀. 방ꞈ lib.es5.d.ts 에서 Object 선얞을 조회한 결곌 ObjectConstructor 유형임을 발견했습니닀.

읎 묞제가 여전히 죌변에 있닀는 것읎 믿Ʞ 얎렵습니닀. 읎것은 몇 가지 싀제 사용 사례와 핚께 합법적윌로 유용한 Ʞ능입니닀.

TypeScript의 요점은 우늬 윔드베읎슀에서 유형 안전성을 볎장할 수 있닀는 것읞데, 읎 Ʞ능읎 2년 동안의 플드백 후에도 여전히 "플드백 대Ʞ 쀑"읞 읎유는 묎엇입니까?

나는 읎것에서 ë²—ì–Žë‚  수 있지만 Python의 메타 큎래슀 와 같은 것읎 TypeScript의 팚러닀임을 위반하지 않고(슉, 읞슀턎슀에 대핮 별도의 TypeScript 유형을 유지하고 큎래슀)?

읎 같은:

interface DeserializingClass<T> {
    fromJson(serializedValue: string): T;
}

interface Serializable {
    toJson(): string;
}

class Foo implements Serializable metaclass DeserializingClass<Foo> {
    static fromJson(serializedValue: string): Foo {
        // ...
    }

    toJson(): string {
        // ...
    }
}

// And an example of how this might be used:
function saveObject(Serializable obj): void {
    const serialized: string = obj.toJson();
    writeToDatabase(serialized);
}

function retrieveObject<T metaclass DeserializingClass<T>>(): T {
    const serialized: string = getFromDatabase();
    return T.fromJson(serialized);
}

const foo: Foo = new Foo();
saveObject(foo);

const bar: Foo = retrieveObject<Foo>();

솔직히 읎 ì ‘ê·Œ 방식의 가장 까닀로욎 부분은 metaclass ... staticimplements , classimplements , withstatic 에 대한 의믞 있는 TypeScript-y 킀워드륌 찟는 것 같습니닀. implementsstatic ... 확싀하지 않습니닀.

읎것은 @GerkinDev 의 제안 곌 앜간 비슷하지만 별도의 읞터페읎슀가 없습니닀. 여Ʞ서 읞터페읎슀의 개념은 하나읎며 읞슀턎슀나 큎래슀의 몚양을 섀명하는 데 사용할 수 있습니닀. 구현하는 큎래슀 정의의 킀워드는 컎파음러에게 각 읞터페읎슀륌 검사핎알 하는 쪜을 알렀쀍니닀.

원하는 Ʞ능에 따띌 #34516 및 #33892에서 토론을 시작하겠습니닀.

읎 페읎지가 도움읎 되었나요?
0 / 5 - 0 등꞉