ë©ìë ì ìžìì abstract
ìììŽë¥Œ íì©íì§ë§ ì ì ë©ìë ì ìžììë íì©íì§ ìë ì°ì #2947 묞ì ë¡, ë©ìë ì ìžìì abstract static
ìììŽë¥Œ íì©íì¬ ìŽ êž°ë¥ì ì ì ë©ìë ì ìžìŒë¡ íì¥íë ê²ìŽ ì¢ìµëë€. .
êŽë š 묞ì ë íì©ëì§ ìë ìží°íìŽì€ ë©ìë ì ìžì static
ìì ìì êŽë šìŽ ììµëë€.
ì¶ì íŽëì€ì ê·ž 구íì ì¬ì©íë ìŒë¶ 겜ì°ìë ìŒë¶ íŽëì€ ì¢
ì(ìžì€íŽì€ ì¢
ì ìë) ê°ìŽ íìí ì ììµëë€. ê°ì²Ž ìì±. ìŽë¥Œ íì©íë êž°ë¥ì ë©ìë ì ìžì 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' ìì±ìŽ ì¡Žì¬íì§ ììµëë€.ëŒë ë©ìì§ë¥Œ íìí©ëë€.
겜ì°ì ë°ëŒ ìží°íìŽì€ ë ŒëŠ¬ë 구í íŽëì€ì 믞늬 ê²°ì ë ë§€ê° ë³ì 목ë¡ìŽ ìê³ ì íí ì íì ê°ì ë°ííë ì ì ë©ìëê° ììŽìŒ íšì ì믞í©ëë€.
ì(ì 3):
interface Serializable {
serialize(): string;
static deserialize(serializedValue: string): Serializable; // error: 'static' modifier cannot appear on a type member.
}
ìŽ ìœë륌 컎íìŒí ë ì€ë¥ê° ë°ìí©ëë€. 'ì ì ' ìì ìë íì ë©€ë²ì ëíë ì ììµëë€.
ë 묞ì (1.1 ë° 1.2)ì ëí ì룚ì
ì ì¶ì íŽëì€ì ì ì ë©ìë ì ìžì $#$1 abstract
#$ ìì ì륌 íì©íê³ ìží°íìŽì€ì static
ìì ì륌 íì©íë ê²ì
ëë€.
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));
abstract static
ìì ìë¡ íìëìŽìŒ í©ëë€.abstract static
ëë static
ìì ìë¡ íìëìŽìŒ í©ëë€.static
ìì ìë¡ íìëìŽìŒ í©ëë€.static
ìì ìë¡ íìëìŽìŒ í©ëë€.abstract static
abstract
ë° static
ìì ì ìì±ìì ììëìŽìŒ í©ëë€.
static
ìží°íìŽì€ ë©ìë ìì ìì ë€ë¥ž 몚ë ìì±ì ìží°íìŽì€ ë©ìë ë° static
ìì ì ìì±ìì ììëìŽìŒ í©ëë€.
abstract static
static
ìììŽì
ëë€.abstract static
static
ìì ì륌 컎íìŒíë ë° ì€ë¥ê° ììµëë€. ì ì ìží°íìŽì€ ë©ìëë ìŒë°ì ìŒë¡ ìë¯žê° ììµëë€. #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륌 ì²ì ì¬ì©íì§ë§ Ʞ볞ì ìŒë¡ ìŽê²ìŽ íì©ëì§ ìëë€ë ì 곌 ë§ì ì¬ëë€ìŽ ë€ì ì€ íëë¡ êž°ë¥ì ì¶ê°íì§ ìë ê²ì ì ë¹ííë €ê³ íë€ë ì¬ì€ì ëëìµëë€.
ë ë€ë¥ž ê°ëší ì¬ì© ì¬ë¡: (ìëíì§ ìë ìŽìì ìž ë°©ë²)
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
륌 ì ìí©ëë€. ìŽë¬í ëë €ìŽ íŽê²° ë°©ë²ì ì¬ì©íë©Ž ì ì ì¬ìŽížìì 몚ìì íìží ì ìì§ë§(겜ì°ì ë°ëŒ) 묞ì ê° ììµëë€.
#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
````íìŽíì€í¬ëŠœíž
ìží°íìŽì€ ì ì© íì¥ ì ì© {(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 =
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ë ì ë¥íì íëëê»ì íëžëŠ¿ìŒë¡ 볎ëŽì ê²ìŽ ìëë©°, ìë€ê³ íëëŒë íŽìì ìì ëê° ììµëë€. ë¹ì ì ë¹ì ìŽ ê·žê²ì ëíŽ ìíë ë§íŒ ìŽì죌ìì ìŒ ì ìì§ë§, ì ê² ë¶íì ë€ìŽ 죌ììì€. ë¹ì ì 믿ìì ì§ì ì¬íì íŒëšëŠ¬ì§ ë§ììì€. 몚ë ì¬ëì ìíë ë°©ììŒë¡ 몚ë ë구륌 ì¬ì©íê³ ê·žê° ìê³ ìë 몚ë ê°ë¥í ê·ì¹ì ìë°í ì ìë 몚ë ê¶ëŠ¬ê° ììµëë€(ìŽìžì ëíŽ ì¹Œì ë¹ëí ìë ììµëë€). ë구ì íì§ì ì ìíë ê²ì í¹ì êž°ë¥ì ëí ììì ê·žì ëí ì ì ê°ì ê· íì ëë€. ê·žëŠ¬ê³ ìŽ ë¶êž°ë ììëì 볎ì¬ì€ëë€. ìŽ êž°ë¥ìŽ íìíì§ ìë€ë©Ž ì¬ì©íì§ ë§ììì€. ê·žë ë€. ê·žëŠ¬ê³ ì¬êž° ìë ë§ì ì¬ëë€ë ê·žê²ì íìë¡ íê³ _ì°ëŠ¬ë_ ì€ì©ì ìž ì¬ì© ì¬ë¡ë¥Œ ê°ì§ê³ ìì§ë§ ì€ì ë¡ë ì°ëŠ¬ê° ê·žê²ì 묎ìíŽìŒ íë€ê³ ë§íê³ ììµëë€. ê·žê²ì ì ì§ìë€ìê² ë ì€ìí ê², ìŠ ì ì±í ìì¹(ê·žë€ìŽ ìŽíŽíë ë°©ìì ìêŽììŽ) ëë 컀뮀ëí°ì êŽí ê²ì ëë€.
ìŽë€ ì¢ì ì ìì ì¬ì© ì¬ë¡ë¥Œ ì ê³µíì§ë§ ìŽ ì ìì
ê·žëì ëë ëšì§ ìœê°ì ížêž°ì¬ì íííê³ ì§ë¬žì íìµëë€. ì ìììë ê·žê²ì ë§íì§ ìêž° ë묞ì, ì ì¬ëë€ìŽ ê·žê²ì íìë¡ íëì§
ê·žê²ì ì íì ìž ê²ìŒë¡ ììœë©ëë€. ì ë¹í ìŽì , ê°ííì§ ë§ììì€
ê°ìžì ìŒë¡ ëë 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
ë±ìŽ ììŽìŒ íë ìŽì 륌 ì€ëª
í ê°ì¹ê° ìë ìžìê° ììµëê¹?
ì ê·žê²ìŽ ì ì©íì§ ë³Žì¬ì£Œë ì ììŽ ë ìì ì ììµëê¹?
ìë§ë ì°ëŠ¬ë 묞ì 륌 ì 늬íê³ ë Œìë ëŽì©ì ììœíì¬ íŽê²°ì± ì ì°ŸììŒ í ê²ì ëë€.
ëŽê° ìŽíŽíë ë ê°ì§ ì ììŽ ììµëë€.
interface ISerializable<T> {
static fromJson(json: string): T;
}
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 -449610196
@greeny ë ìëíë ì룚ì ì ëë€. https://github.com/Microsoft/TypeScript/issues/14600#issuecomment -437071092
í¹í ìŽ ë¶ë¶:
type MyClass = (new (text: string) => MyInterface) & { myStaticMethod(): string; }
ë ë€ë¥ž ì¬ì© ì¬ë¡: ìì±ë ìœë/ë¶ë¶ íŽëì€ 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ë ì í ê²ì¬ê° ë¶ê°ë¥íêž° ë묞ì ë°íìì ì€ë¥ê° ë°ìíëëŒë 몚ë ì í ìëª ì ì ê³µí ì ììµëë€.
ìë°ì€í¬ëŠœíž ìì²Žê° ì ì ìž ê±ž ì 못íŽì ìŽ ë¬žì ê° ì¬êž° ì€ë ì¡Žì¬íë ê² ê°ìì ð€
ì ì ììì ì ìŽì ì¡Žì¬íŽìë ì ë©ëë€. ð€ð€
ëê° ì ì ë©ìë륌 ížì¶íê±°ë ì ì íë륌 ìœê³ ì¶ìµëê¹? ð€ð€ð€
ë€ë¥ž ì¬ì© ì¬ë¡ê° ììµëê¹?ð€ð€ð€ð€
ìŽê²ì ëí ì ë°ìŽížê° ììµëê¹?
ëììŽ ëë€ë©Ž íŽëì€ì ì ì ìží°íìŽì€ë¥Œ ì ë ¥íŽìŒ íë 겜ì°ì ìíí ìì ì ë°ìœë ìŽí°ë¥Œ ì¬ì©íì¬ íŽëì€ì ì ì ë©€ë²ë¥Œ ì ì©íë ê²ì ëë€.
ë°ìœë ìŽí°ë ë€ì곌 ê°ìŽ ì ìë©ëë€.
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ì ë³µì ë³žìŽ ìëëê¹? ð
ìží°íìŽì€ì ì ì ë©ìëë ì¶ì íŽëì€ì ì ì ì¶ì ë©ìë륌 ì¬ì©íë ê²ë§íŒ ì§êŽì ìŽì§ ìì ê² ê°ìµëë€.
ìží°íìŽì€ë íŽëì€ê° ìë ê°ì²Žë¥Œ ì ìíŽìŒ íêž° ë묞ì ìží°íìŽì€ì ì ì ë©ìë륌 ì¶ê°íë ê²ì ìœê° ì€ìŒì¹ì ìŽëŒê³ ìê°í©ëë€. ë°ë©Žì ì¶ì íŽëì€ë íì íŽëì€ë¥Œ ì ìíë ë° ì¬ì©ëë¯ë¡ ì¶ì íŽëì€ìë ì ì ì¶ì ë©ìëê° ììŽìŒ í©ëë€. ìŽ êµ¬íìŽ ì§íëë í, ì¶ì íŽëì€ë¥Œ íì¥í ë(ì: 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ìì í ë¡ ì ììíê² ìµëë€.
ê°ì¥ ì ì©í ëêž
Serializableì íì íŽëì€ìì ì ì ìì§ë ¬í ë©ìë륌 ê°ì ë¡ êµ¬ííê³ ì¶ìµëë€.
ê·žë¬í ëìì 구ííêž° ìí íŽê²° ë°©ë²ìŽ ììµëê¹?