ã¡ãœãã宣èšã§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'.
}
}
ãã®çµæãã³ã³ãã€ã©ã¯ãšã©ãŒãçºçãããšå€æãã次ã®ã¡ãã»ãŒãžã衚瀺ããŸãããããã㣠'getSomeClassDependentValue'ã¯ã¿ã€ã 'typeofAbstractParentClass'ã«ååšããŸããã
å Žåã«ãã£ãŠã¯ãã€ã³ã¿ãŒãã§ãŒã¹ããžãã¯ã¯ãå®è£ ã¯ã©ã¹ã«éçã¡ãœãããå¿ èŠã§ããããšãæå³ããŸãããã®ã¡ãœããã¯ãäºåã«å®çŸ©ããããã©ã¡ãŒã¿ãŒã®ãªã¹ããæã¡ãæ£ç¢ºãªåã®å€ãè¿ããŸãã
äŸïŒäŸ3ïŒïŒ
interface Serializable {
serialize(): string;
static deserialize(serializedValue: string): Serializable; // error: 'static' modifier cannot appear on a type member.
}
ãã®ã³ãŒããã³ã³ãã€ã«ãããšããšã©ãŒãçºçããŸãããstaticã修食åãåã¡ã³ããŒã«è¡šç€ºã§ããŸããã
äž¡æ¹ã®åé¡ïŒ1.1ãš1.2ïŒã®è§£æ±ºçã¯ãæœè±¡ã¯ã©ã¹ã®éçã¡ãœãã宣èšã§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ã®è°è«ã®äž»èŠãªãã€ã³ãã®1ã€ã§ããïŒãããã«ãã£ãŠå°ãããŸã芳ç¹ããã while
ãµã€ã¯ã«ã¯ã for
ãšif
ãäžç·ã«äœ¿çšããŠå®è£
ã§ãããããåé·ã§ãããšå€æã§ããŸãã ãã ãã while
ãå»æ¢ããã€ããã¯ãããŸããã
ãããæ€èšãããšãã«ç§ãã¡ãæã£ãŠããäž»ãªè³ªåïŒèª°ã
abstract static
ã¡ãœãããåŒã³åºãããšãã§ããŸããïŒ ãããããAbstractParentClass.getSomeClassDependentValue
ãçŽæ¥åŒã³åºãããšã¯ã§ããŸããã ããããã¿ã€ãAbstractParentClass
ã®åŒã§ã¡ãœãããåŒã³åºãããšã¯ã§ããŸããïŒ ãããããªãããªããããèš±å¯ãããã¹ãã§ããïŒ ããã§ãªãå Žåããã®æ©èœã®çšéã¯äœã§ããïŒ
è¯ã質åã ãã®åé¡ãæ€èšããŠããã®ã§ãããã«ã€ããŠã®ã¢ã€ãã¢ãæããŠãã ããã
ã³ã³ãã€ã©ã¬ãã«ã§ã¯ã AbstractParentClass.getSomeClassDependentValue
ã®çŽæ¥åŒã³åºãã®å Žåã¯è¿œè·¡ãããïŒè¿œè·¡ã§ããªãããïŒãJSã©ã³ã¿ã€ã ãšã©ãŒãçºçããããšã«æ°ä»ãã ãã§ãã ãããããããTypeScriptã®ã€ããªãã®ãŒãšäžèŽããŠãããã©ããã¯ããããŸããã
ç§ã¯ãããã®æ©èœãä»ã®æ段ã§å®è£ ã§ããããšã ããèŠãŸããïŒããã¯ããããç¡æå³ã§ã¯ãªãããšã蚌æããŸãïŒã
äœããå®è£ å¯èœã§ãããšããçç±ã ãã§ããããçã«ããªã£ãŠãããšããæå³ã§ã¯ãããŸããã ð
abstract class Serializable {
abstract serialize (): Object;
abstract static deserialize (Object): Serializable;
}
Serializableã®ãµãã¯ã©ã¹ã«éçdeserializeã¡ãœããã匷å¶çã«å®è£
ããããšæããŸãã
ãã®ãããªåäœãå®è£
ããããã®åé¿çã¯ãããŸããïŒ
ããã«é¢ããææ°ã®èŠè§£ã¯äœã§ããïŒ æœè±¡ã¯ã©ã¹ã®æœè±¡éçããããã£ãæžã蟌ãããšãããšãããèš±å¯ãããŠããªãããšã«æ¬åœã«é©ããŠããŸããã
@ patryk-zielinski93ãèšã£ãããšã ç§ãã¡ãTSã«å€æããPHPã®æ°å¹Žã®ãããžã§ã¯ãããæ¥ãŠãç§ãã¡ã¯ã€ã³ã¿ãŒãã§ãŒã¹ã«éçã¡ãœãããå¿ èŠã§ãã
ããã圹ç«ã€éåžžã«äžè¬çãªãŠãŒã¹ã±ãŒã¹ã¯ãReactã³ã³ããŒãã³ãã§ããããã¯ã displayName
ã propTypes
ã defaultProps
ãªã©ã®éçããããã£ãæã€ã¯ã©ã¹ã§ãã
ãã®å¶éã®ãããReactã®åæå®ã«ã¯ãçŸåš2ã€ã®åãå«ãŸããŠããŸãã Component
ã¯ã©ã¹ãšãã³ã³ã¹ãã©ã¯ã¿ãŒé¢æ°ãšéçããããã£ãå«ãComponentClass
ã€ã³ã¿ãŒãã§ã€ã¹ã§ãã
ãã¹ãŠã®éçããããã£ãåããReactã³ã³ããŒãã³ããå®å šã«åãã§ãã¯ããã«ã¯ãäž¡æ¹ã®åã2ã€äœ¿çšããå¿ èŠããããŸãã
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))
}
}
@roboslone
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ããã€ã³ã¹ã¿ã³ã¹åå¯èœã§ããããšã瀺ãã³ã³ãã©ã¯ããæäŸããã€ã³ã¿ãŒãã§ãŒã¹ãå®çŸ©ããããšã¯å®å šã«çã«ããªã£ãŠããŸãã
æœè±¡éçãã¡ã¯ããªã¡ãœãããèš±å¯ããªãå Žåãå®è£ è ã¯ä»£ããã«æœè±¡ãã¡ã¯ããªã¯ã©ã¹ãäœæããå¿ èŠããããã¯ã©ã¹å®çŸ©ã®æ°ãäžå¿ èŠã«2åã«ãªããŸãã ãããŠãä»ã®ãã¹ã¿ãŒãææããŠããããã«ãããã¯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 /æ§æãäœæããæ段ãšããŠãã¯ã©ã¹ãããã©ã«ãå€ãªããžã§ã¯ããŸãã¯ãããäœã§ãããæå®ããããšãä¿èšŒããŸãã -ãããŠãããªãã¯èããŠãããããããŸããããŸããããã€ã³ã¿ãŒãã§ãŒã¹ã®ç®çã§ãã ãããããã®ãããªåçŽãªãã®ã®å Žåãããã¯å®éã«ã¯æå³ããªããå¿ èŠä»¥äžã«è€éã«ãªãã ãã§ãïŒãµãã¯ã©ã¹ã¯æœè±¡ã¯ã©ã¹ãæ¡åŒµããããã€ãã®ã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããå¿ èŠããããååä»ããããè€éã«ãªããŸããçïŒã
ç§ã®ãããžã§ã¯ãã«ã¯ããããšåæ§ã®èŠä»¶ã2åãããŸããã ãããã¯äž¡æ¹ãšãããã¹ãŠã®ãµãã¯ã©ã¹ãäžé£ã®éçã¡ãœããã®å ·äœçãªå®è£ ãæäŸããããšãä¿èšŒããããšã«é¢é£ããŠããŸããã ç§ã®ã·ããªãªã¯ä»¥äžã®ãšããã§ãã
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
ã¡ã³ããŒã掟çã¯ã©ã¹ã®å®è£
ã«ãã£ãŠå®éã«_ãªãŒããŒã©ã€ã_ãããCïŒãªã©ã®èšèªãšã¯ç°ãªããJavaScriptã¡ã³ããŒã®å®è£
ã¯ãã€ã³ã¹ã¿ã³ã¹ãªã©ã§ã¯ãç¶æ¿ãããæ°å€ããªãŒããŒã©ã€ãããããšã¯ãªããããããããã_ã·ã£ããŠ_ããããšãèæ
®ããããšãéèŠã§ãã
ããã§ã®ç§ã®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ã®2ã€ã®æ©èœãå¿
èŠã§ããïŒ1ïŒã€ã³ã¿ãŒãã§ã€ã¹ã®éçã¡ãœãããšæœè±¡éçã¡ãœããã ïŒ2ïŒãžã§ããªãã¯ã¯ã©ã¹ã®åãã³ããšããŠtypeof
ã䜿çšããæ©èœã
@davidmpaz
ãã®éšåãããããŸããã§ããã
ã¯ã©ã¹ã«ã¯2ã€ã®ã€ã³ã¿ãŒãã§ãŒã¹ããããŸãã ã³ã³ã¹ãã©ã¯ã¿ãŒé¢æ°ãšã€ã³ã¹ã¿ã³ã¹ã®ãããã¿ã€ãã ããŒã¯ãŒã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()
ã¯ã³ã³ã¹ãã©ã¯ã¿ãŒã«ã®ã¿ååšããŸãã
ã¿ã€ãã®èŠ³ç¹ããããã®2ã€ã®ã€ã³ã¿ãŒãã§ãŒã¹ãåç
§/æœåºã§ããŸãã 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
$ã®ã¿ãåŒã³åºããŸããããªããžã§ã¯ããã€ã³ã¹ã¿ã³ã¹åããŠãã䜿çšããããšã¯éåžžã«äžè¬çã§ãã makeInstance
å
ã«$ T
ãäœã§ããããå®éã«ã¯ããããªãããã 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
å¥ã¯å¿
èŠãããŸããã èšåçåã·ã¹ãã ã§ã¯ãã¯ã©ã¹ã§ãisaãé¢ä¿ãè¡šæããããã«æ¬åœã«å¿
èŠã§ãã æ§é åã·ã¹ãã ã§ã¯ãå®éã«ã¯å¿
èŠãããŸããã ãisaãã®é¢ä¿ã¯ãšã«ãã䜿çšãããã³ã«ãã§ãã¯ãããã®ã§ãå®å
šæ§ã倱ãããšãªãã implements
å¥ãå®å
šã«åé€ã§ããŸãã
ã€ãŸããéçãªfromJSON
ãæã¡ãã€ã³ã¹ã¿ã³ã¹ã«toJSON
ãæã€1ã€ã®ã¯ã©ã¹ãæã€ããšãã§ããŸãã
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> {
...
}
ãã®æç¹ã§ãtypescriptã«ãã£ãŠãã§ãã¯ãããã³ãŒãå ã®äœ¿çšãµã€ããããå Žåã¯ã匟䞞ãããã£ãŠããããæ¬åœã«é ãã«ããå Žåã§ãããããä¿¡é Œããå¿ èŠããããŸãã
ãµã€ããå€éšã§äœ¿çšããŠããå Žåã¯ãã³ãã¥ããã£/ã¡ã³ããã«ã€ã³ã¿ãŒãã§ã€ã¹ã¡ã³ããŒã®static
修食åãåãå
¥ããããã«èª¬åŸããŠãã ããã ãããŸã§ã®éãå¥ã®åé¿çãå¿
èŠã«ãªããŸãã å®çŸ©ãµã€ãã«ã¯ãããŸããããïŒ8328ã§èª¬æãããŠããåé¿çã®ä¿®æ£ããŒãžã§ã³ã䜿çšããŠãããå®çŸã§ãããšæããŸãã @RyanCavanaughã®åæã«ããã2016幎5æ16æ¥ã®@mhegazyããã®ã³ã¡ã³ãã§åé¿çãåç
§ããŠãã ããã
éèŠãªãã€ã³ããæ¬ ããŠããå Žåã¯ã容赊ãã ããã ã€ã³ã¿ãŒãã§ã€ã¹ã¡ã³ããŒã®static
ããµããŒãããããšãããããããšã«ã€ããŠã®ç§ã®ç解ã¯ãäž»ã«ãã³ã³ã¹ãã©ã¯ã¿ãŒã®åœ¢ç¶ãšã€ã³ã¹ã¿ã³ã¹ã®åœ¢ç¶ã®äž¡æ¹ãèšè¿°ããããã«åãã€ã³ã¿ãŒãã§ã€ã¹+ implementsããŒã¯ãŒãã䜿çšããããšãå«ãããšã§ãã
次ã®äŸãã®åã«ãtypescriptãæäŸãããã®ã倧奜ãã§ãtypescriptãéçºãã人ã ãšãå€æ°ã®æ©èœèŠæ±ã«å¯ŸåŠããããã«å€ãã®èããšåªåã泚ãã§ããã³ãã¥ããã£ã«æè¬ããŸãã æé©ãªæ©èœãå®è£ ããããã«æåãå°œãããŠããŸãã
ãããããã®å Žåã®èºèºã¯ã䜿ãããããç ç²ã«ããŠãæŠå¿µçãªçŽç²ãããç¶æããããšããé¡æãšããŠç§ã«ã¯èŠããŸãã ãã®ã¢ãããžãŒãããŒã¹ãã倧ããå€ããŠããå Žåã¯ãããäžåºŠç³ãèš³ãããŸããã
ããã¯ã Java
ããC#
$ãžã®åãæ¿ããæãåºãããŸãã C#
ã³ãŒãããããå®è¡ããŠããã®ãæåã«èŠããšãC#
var something = "something";
if(something == "something") {
...
}
ç®èŠãŸããã«ãé ã®äžã§é³Žãå§ããäžçã¯çµãããåãã "something".Equals(something)
ãªã©ã䜿çšããå¿
èŠããããŸãã
==
ã¯åç
§çšã§ãïŒ æååæ¯èŒçšã«å¥ã®.Equals(...)
ããããŸã...
ãããŠãæååãªãã©ã«ãæåã«æ¥ãå¿
èŠãããã®ã§ãnullå€æ°ã§.EqualsïŒ...ïŒãåŒã³åºãnullrefãååŸããŸããã
ãããŠ...ãããŠ...éåŒåž
ãããŠã C#
ãæ°é±é䜿çšããåŸããã®åäœã®ãããã§ãã©ãã»ã©äœ¿ããããããããããŸããã äž¡è
ã®æ確ãªåºå¥ããããããããšãæå³ããŠããŸããããããã¯äœ¿ãããããåçã«åäžãããã®ã§ãããã ãã®äŸ¡å€ããããŸãã
ããããã€ã³ã¿ãŒãã§ã€ã¹ã¡ã³ããŒã®static
修食åã«ã€ããŠã®ç§ã®æ°æã¡ã§ãã ããã«ããããã§ã«è¡ã£ãŠããããã«ã€ã³ã¹ã¿ã³ã¹ã®åœ¢ç¶ãèšè¿°ãç¶ããããšãã§ããå Žåã«ãã£ãŠã¯äžååãªåé¿çã§ã®ã¿å®è¡ã§ããã³ã³ã¹ãã©ã¯ã¿ãŒé¢æ°ã®åœ¢ç¶ãèšè¿°ã§ããæ¯èŒçã¯ãªãŒã³ã§ç°¡åãªäž¡æ¹ãå®è¡ã§ããŸããä»æ¹ã 䜿ããããã®å€§å¹
ãªåäžãIMOã
次ã®ã³ã¡ã³ãã§abstract static
ãæ€èšããŸãã
ã€ã³ã¿ãŒãã§ã€ã¹ã¯åžžã«ã匷å¶çãªã¯ã©ã¹ã®ã¡ã³ããŒã¿ã€ãã®åæå®ãå¿ èŠãšããŸãã ïŒ_explicitly_å®è£ ã¯ã©ã¹ã§ã®ã¡ã³ããŒçœ²åã®æšè«ã¯ãå¥åã®ããŸã ãµããŒããããŠããªãæ©èœã§ãïŒã
ãšã©ãŒãçºçããçç±ã¯ããã®ææ¡ãšã¯é¢ä¿ãããŸããã ãããåé¿ããã«ã¯ãéçãŸãã¯ãã®ä»ã®ãªãã©ã«åã§ããå¿
èŠãããã¯ã©ã¹ã¡ã³ããŒã®å®è£
ã§readonly
修食åã䜿çšããå¿
èŠããããŸãã ãã以å€ã®å Žåã¯ã string
ãæšæž¬ãããŸãã
ç¹°ãè¿ããŸããã implements
ããŒã¯ãŒãã¯åãªãæå³ã®ä»æ§ã§ãããåã®æ§é çãªäºææ§ã«åœ±é¿ãäžããããåç®äžã®åä»ããå°å
¥ãããããããšã¯ãããŸããã ããã圹ã«ç«ããªãã£ããšããããã§ã¯ãããŸããããããã¯ã¿ã€ããå€æŽããŸããã
ã ããabstract static
...ããã ãã®äŸ¡å€ã¯ãããŸããã åé¡ãå€ãããŸãã
䜿çšãµã€ãã§æé»çã«ãã§ãã¯ããããã®ã宣èšããã«ã¯ãæ°ããè€éãªæ§æãå¿ èŠã«ãªããŸãïŒäœ¿çšãµã€ããtypescriptã³ã³ãã€ã©ã«ãã£ãŠãã§ãã¯ãããå ŽåïŒã
䜿çšãµã€ããå€éšã®å Žåãæ¬åœã«å¿
èŠãªã®ã¯ã€ã³ã¿ãŒãã§ã€ã¹ã®static
ã¡ã³ããŒã§ã...ãã©ã°ã€ã³ãå®äºããŠç³ãèš³ãããŸãã....ãããŠãããã¿ãªããïŒ
@aluanhaddadæ¬åœã§ãããã¯ã©ã¹ãæ瀺çã«å®è£ ããéã®ã¡ã³ããŒçœ²åã®æšè«ããµããŒããããŠããæ©èœã§ãã£ããšããŠããã¯ã©ã¹ã®éçåŽã®ã¡ã³ããŒçœ²åã宣èšããã¯ãªãŒã³ãªæ¹æ³ããããŸããã
ç§ãè¡šçŸããããšããŠããã®ã¯ãã¯ã©ã¹ã®éçåŽã®äºæ³ãããæ§é ãexplicitly
宣èšããæ¹æ³ããªãããããéèŠã§ããïŒãŸãã¯æ©èœããµããŒãããããã«éèŠã«ãªãïŒå Žåããããšããããšã§ããã
äž»ã«ãã³ã¡ã³ãã®ãã®éšåã«ã€ããŠããã¯ã©ã¹ã®éçåŽã®èŠä»¶ãæå®ããã€ã³ã¿ãŒãã§ãŒã¹ãæ§æçã«åç §ãããŠãããã©ããã¯é¢ä¿ãããŸããããšåè«ããããšæããŸãã
å°æ¥ã®ãµããŒãã§éèŠã«ãªãçç±ã®äŸãšããŠãåæšè«ã䜿çšããããšããŠããŸããã
ããã§ã€ã³ã¿ãŒãã§ãŒã¹ãæ§æçã«åç
§ããããšã«ããã let something: ISomethingStatic = { isFlammable: 'Ys', isFlammable2: 'No' ... isFlammable100: 'No' }
ã¯ãåããã¯ãããšããŠæ瀺çã«å®£èšããå¿
èŠã¯ãããŸããã ããããã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
ã«èªåçã«è¿œå ããããšãå®è£
ãããŠããªãå Žåã§ããæåã§"constructor": typeof AbstractParentClass
ã宣èšããããšã«ãããåºæ¬ã¯ã©ã¹ã§abstract static
ããããã£ã䜿çšã§ããŸãã
å€ãã®äººã@ patryk-zielinski93ã®äŸãæ©èœããããšãæåŸ ããŠãããšæããŸãã 代ããã«ãçŽæã«åãããåé·ã§äžå¯è§£ãªåé¿çã䜿çšããå¿ èŠããããŸãã ãã§ã«ãæ§æç³åãã¯ã©ã¹ãšéçã¡ã³ããŒãããã®ã«ããªããã®ãããªç³ãåã·ã¹ãã ã«å«ããããšãã§ããªãã®ã§ããããã
ãããç§ã®çã¿ã§ãïŒ
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ã®ææ¡ã«æççãªäººãã¡ã®è°è«ãã©ããªã«ç解ããããšããŠã倱æããŸããã
@RyanCavanaughã«åçããã®ã¯1人ã ãïŒhttps://github.com/Microsoft/TypeScript/issues/14600#issuecomment-379645122ïŒã§ãã 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ã¯ãšã©ãŒã§ãã ããããããã§ãfooããåŒã³åºãããšã¯ã§ããŸããã baz
ã¯Child1ãŸãã¯Child2ã®__instance__ã§ãããšæ³å®ãããŠãããã€ã³ã¹ã¿ã³ã¹ã«ã¯éçã¡ãœããããªãããã§ãã
refïŒ4ã¯æ£ããïŒæ£ããã¯ãã§ãïŒã baz
ã¯ãBaseãæ¡åŒµããChild1ãŸãã¯Child2ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã§ãããšæ³å®ãããŠãããããããã§éçã¡ãœããfooãåŒã³åºãããšãã§ããŸãïŒã§ããã¯ãã§ãïŒããããã£ãŠã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).
ãã®æ©èœã®çšéã¯äœã§ããïŒ
refïŒ4ãåç
§ããŠãã ãããåŒæ°ãšããŠåãåãåã¯ã©ã¹ïŒChild1ãŸãã¯Child2ã®å¯èœæ§ããããŸãïŒãããããªãããéçã¡ãœãããåŒã³åºããŠããã®ã¡ãœãããååšããããšã確èªããå Žåã«äœ¿çšããŸãã
ç§ã¯AdonisJSãšåŒã°ããnode.jsãã¬ãŒã ã¯ãŒã¯ãæ£ããæžãçŽããŠããŸãã çŽç²ãªJSã§æžãããŠããã®ã§ãTSã«å€æããŠããŸãã ã³ãŒãã®åäœãå€æŽããããšã¯ã§ããŸãããã¿ã€ããè¿œå ããã ãã§ãã ãã®æ©èœããªãã®ã§ããšãŠãæ²ãããªããŸãã
psãã®ã³ã¡ã³ãã§ã¯ãç°¡åã«ããããã«ãæœè±¡ã¯ã©ã¹ã«ã€ããŠã®ã¿èšè¿°ããã€ã³ã¿ãŒãã§ãŒã¹ã«ã€ããŠã¯èšåããŸããã§ããã ããããç§ãæžãããã®ã¯ãã¹ãŠã€ã³ã¿ãŒãã§ãŒã¹ã«é©çšã§ããŸãã æœè±¡ã¯ã©ã¹ãã€ã³ã¿ãŒãã§ãŒã¹ã«çœ®ãæããã ãã§ããã¹ãŠãæ£ãããªããŸãã äœããã®çç±ã§ïŒçç±ãããããªãïŒTSããŒã ãabstract class
ã«abstract static
ãå®è£
ããããªãå Žåã¯ãå¯èœæ§ããããŸããã static
ã®ã¿ãå®è£
ããããšã¯åé¡ãããŸãããã€ã³ã¿ãŒãã§ã€ã¹ã®åèªãããã¯ç§ãã¡ãååã«å¹žãã«ããã§ããããç§ã¯æšæž¬ããŸãã
pps質åã®ã¯ã©ã¹åãšã¡ãœããåãç·šéããŠãã³ãŒãã«æºæ ãããŸããã
ä»ã®æçè«è ã®äž»ãªè°è«ã«åºã¥ããããã€ãã®èãïŒ
ãããããããã¯å®è£ ããŠã¯ãããŸãããããã§ã«ãã®æ¹æ³ã§å®è£ ã§ããŸã* 15å以äžã®ã³ãŒãè¡ãèšè¿°ããŸã*ãã
ãããæ§æç³è¡£ã®ããã«äœãããŠãããã®ã§ãã TSã«å°ãïŒç ç³ïŒãå ããŸãããã ããããããããã€ã³ã¿ãŒãã§ã€ã¹ã«1ã€ã®åçŽãªstatic
åèªãè¿œå ããã®ã§ã¯ãªãããã³ã¬ãŒã¿ãšæ°åã®ãžã§ããªãã¯ãçªç Žããããšããéçºè
ã®é è³ãæ·åããã»ããããã§ãããã ãã®static
ãç§ãã¡ã®ç掻ã楜ã«ããå¥ã®ç ç³ãšèããŠã¿ãŸãããïŒ ES6ãclass
ãè¿œå ããã®ãšåãæ¹æ³ã§ïŒããã¯æè¿ãŠããã¿ã¹ã«ãªããŸãïŒã ããããããããç§ãã¡ã¯ãªã¿ã¯ã«ãªããå€ããŠãæ£ãããæ¹æ³ã§ç©äºãè¡ããŸãããã
ãjsã¯ã©ã¹ã«ã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒãšã€ã³ã¹ã¿ã³ã¹ã®2ã€ã®ã€ã³ã¿ãŒãã§ãŒã¹ããããŸããã
ã§ã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒã®ã€ã³ã¿ãŒãã§ãŒã¹ãäœæããæ¹æ³ãæããŠãã ããã ãã ãããã®static
åèªãè¿œå ããã ãã§ãã¯ããã«ç°¡åã§çŽæçã«ãªããŸãã
ãããŠããã«é¢ããŠïŒ
ããã«ã€ããŠã®ãã£ãŒãããã¯ãããã«èããããŸã§ããããä¿çããŸãã
ãã®åé¡ããã€ãŸã§å»¶æãããã®ãã1幎以äžãçµéããå€ãã®ãã£ãŒãããã¯ãæäŸãããŸãããïŒ èª°ããçããŠããããŸããïŒ
ãã®æçš¿ã¯ã¡ãã£ãšå³ããããã«æãããããããŸãã...ããããããããããã¯TSãæãã人ããã®èŠæ±ã§ãããåæã«ãå€ãJSã³ãŒãããŒã¹ãTSã«å€æãããšãã«ãéãããã¯ãè¡ãã¹ãçç±ã1ã€èŠã€ããããšãã§ããŸããã ãããšã¯å¥ã«ã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
`` `` typescript
interface Applicative extends Apply {ïŒaïŒAïŒã®éçïŒé©çšå¯èœ; }
const of = >ïŒcïŒCãaïŒAïŒïŒnew C => c.ofïŒaïŒ; `` ``
deserialize
ã¡ãœããã䜿çšããSerializable
ã¿ã€ã`` `` typescript
ã€ã³ã¿ãŒãã§ã€ã¹Serializable {
static deserializeïŒsïŒstringïŒïŒSerializable;
serialize(): string;
}
`` ``
`` `` typescript
ã€ã³ã¿ãŒãã§ã€ã¹å¥çŽ{
static createïŒxïŒnumberïŒïŒå¥çŽ;
static newïŒxïŒnumberïŒïŒå¥çŽ;
}
const factory1 =ïŒcïŒéçã³ã³ãã©ã¯ãïŒïŒã³ã³ãã©ã¯ã=> c.createïŒMath.randomïŒïŒïŒ;
const factory2 =ïŒCïŒéçã³ã³ãã©ã¯ãïŒïŒã³ã³ãã©ã¯ã=> new CïŒMath.randomïŒïŒïŒ;
const factory3 =
const c1 = factory1ïŒContractImplïŒ; // Contract
const c2 = factory2ïŒContractImplïŒ; // Contract
const c3 = factory3ïŒContractImplïŒ; // ContractImpl
`` ``
`` `` typescript
ã€ã³ã¿ãŒãã§ã€ã¹Serializable {
static deserializeïŒsïŒstringïŒïŒSerializable;
}
ã¿ã€ãSerializable = {
static deserializeïŒsïŒstringïŒïŒSerializable;
};
æœè±¡ã¯ã©ã¹Serializable {
static abstract deserializeïŒsïŒstringïŒïŒSerializable;
}
`` ``
typescript
interface Contract {
static new(): Contract;
}
è°è«ïŒ
éçãªåŒã³åºã眲åã¯ã©ã®ããã«è¡šçŸã§ããŸããïŒ
åŒã³åºã眲åã®åã«static
修食åãè¿œå ããã ãã§ããããè¡šçŸããå Žåã
'static'
ãšããååã®ã€ã³ã¹ã¿ã³ã¹ã¡ãœãããšã©ã®ããã«åºå¥ããŸããïŒ
'new'
ãšããååã®ã¡ãœãããšåãåé¿çã䜿çšã§ããŸããïŒ
ãã®ãããªå Žåãããã¯ééããªãé倧ãªå€åã«ãªããŸãã
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]]
å
éšã¹ãããã«æ ŒçŽãããŸãã
`` `` typescript
// ã¿ã€ã
ã€ã³ã¿ãŒãã§ã€ã¹Serializable {
static deserializeïŒsïŒstringïŒïŒSerializable;
ã·ãªã¢ã«åïŒæåå;
}
//å
éšçã«æ¬¡ã®ããã«è¡šãããŸã
//ã€ã³ã¿ãŒãã§ãŒã¹Serializable {
// [[éç]]ïŒ{
// [[Instance]]ïŒSerializable; // äžèšåç
§ã
// deserializeïŒsïŒstringïŒïŒSerializable;
//};
// serializeïŒïŒïŒstring;
//}
`` ``
ããã©ã«ãã§ã¯ãã¿ã€ãnever
ã§ãã
[[Instance]]
å
éšã¹ãããã¿ã€ãã®ãã€ã³ã¹ã¿ã³ã¹ãã€ã³ã¿ãŒãã§ãŒã¹ãä¿åãããŸã
[[Static]]
å
éšã¹ãããã¿ã€ãã®[[Instance]]
å
éšã¹ãããã
ããã©ã«ãã§ã¯ãã¿ã€ãnever
ã§ãã
static
æŒç®åãªãåãå€åãšããŠäœ¿çšããå Žåã
[[Static]]
å
éšã¹ãããã¯ç Žæ£ãããŸãïŒ
`` `` typescript
const serializableã宣èšããŸãïŒSerializable;
ã¿ã€ãT =ã·ãªã¢ã«åå¯èœãªã¿ã€ãã
// {serializeïŒïŒïŒstring; }
`` ``
ãã ããã¿ã€ãèªäœã¯[[Static]]
å
éšã¹ããããä¿æãããŸãŸã§ãã
typescript
type T = Serializable;
// {
// [[Static]]: {
// [[Instance]]: Serializable;
// deserialize(s: string): Serializable;
// };
// serialize(): string;
// }
éçèªèã¿ã€ãã®äž¡æ¹ã®å€ã¯ãæ§é çã«åäžã«å²ãåœãŠãããšãã§ããŸã
ïŒãã¡ããã [[Static]]
ãé€ãïŒãã®ãšãã®éã
static
æŒç®å| çµåæ§| åªå
é äœ|
| ïŒ-----------ïŒ| ïŒ--------------------------------ïŒ|
| å³| IDKã§ããã new
ã®ãã®ãšåãã§ã|
static
åæŒç®åã¯ãåã®[[Static]]
å
éšã¹ãããã®åãè¿ããŸãã
typeof
åæŒç®åã«ããã¶ã䌌ãŠããŸããã
ãã ããåŒæ°ã¯å€ã§ã¯ãªãåã§ããå¿
èŠããããŸãã
typescript
type T = static Serializable;
// {
// [[Instance]]: Serializable;
// deserialize(s: string): Serializable;
// }
typeof
åæŒç®åã¯ã [[Instance]]
å
éšã¹ããããç Žæ£ããŸãã
`` `` typescript
const SerializableImplã宣èšããŸãïŒstatic Serializable;
ã¿ã€ãT = typeof SerializableImpl;
// {deserializeïŒsïŒstringïŒïŒSerializable; }
`` ``
ã€ã³ã¹ã¿ã³ã¹å¯Ÿå¿ã¿ã€ãã®äž¡æ¹ã®å€ã¯ãæ§é çã«åäžã«å²ãåœãŠãããšãã§ããŸã
ïŒãã¡ããã [[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]]
å
éšã¹ããããå¿
èŠã§ãã
äºææ§ãã§ãã¯ã¯ããšåãïŒãŸãã¯é¡äŒŒïŒã§ããå¿
èŠããããŸã
å®æçãªïŒã€ã³ã¹ã¿ã³ã¹ïŒäºææ§ãã§ãã¯ã
`` `` typescript
ã¯ã©ã¹SerializableImplã¯Serializable {ãå®è£
ããŸã
static deserializeïŒsïŒstringïŒïŒSerializableImpl {
//éã·ãªã¢ã«åããžãã¯ã¯ããã«ãããŸãã
}
// ...other static members
// constructor
// ...other members
serialize(): string {
//
}
}
`` ``
infer
æŒç®åã䜿çšããç¹æ®ãªã±ãŒã¹ã¯ãããŸããïŒãã®åé¡ãšä»ã®åé¡ãæ°æéãããŠèªãã§ãåé¡ã®åé¿çãèŠã€ããŸãããããã¯ãéç修食åãŸãã¯ã¯ã©ã¹ã®ã€ã³ã¿ãŒãã§ã€ã¹ã«ãã£ãŠè§£æ±ºãããŸãã åé¡ã解決ããåé¿çã1ã€ãèŠã€ãããŸããã
ç§ãæ±ããŠããåé¡ã¯ãã³ãŒãã§çæãããã¯ã©ã¹ã«å€æŽãå ããããšããããšã§ãã ããšãã°ãç§ãããããããšã¯æ¬¡ã®ãšããã§ãã
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ã§ããããšåçã®åé¿çã1ã€èŠã€ããããšãã§ããŸããã çŸåšããã®åé¡ã解決ããæ¹æ³ããããŸãããïŒ
ããã¯ãæããã«åé¿çããªãã確ãã«ç°¡åãªåé¿çããªããŠãŒã¹ã±ãŒã¹ãšããŠããã«æçš¿ããããšã«é¢é£ããŠãããšæããŸãã
ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãšéçåŽãã€ã³ã¿ãŒãã§ãŒã¹ãšç §åããå Žåã¯ã次ã®ããã«è¡ãããšãã§ããŸãã
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ã©ã€ããŒã§ããå¿
èŠããããã®ã«å¯Ÿããããã¹ãŠã®å€§ããªåé¿çã®çãã¯ãªãã§ããã ç§ã®ã³ãŒããããããŒãªåé¿çã§äœãããããšããŠããã®ãã誰ãã«ç解ãããŠã»ãããšããæ¹æ³ã¯ãããŸããã ãã®ãããã¯ãããŸã䟡å€ã®ãªããã®ã§ããã«æ··ä¹±ãããŠç³ãèš³ãããŸããããããã¯çŸåšéåžžã«èŠçã§æéã®ç¡é§ãªã®ã§ãç§ãçŸåšã®ä»ã®äººããããŠåŸã§çããæ¢ããŠãã人ã«ãšã£ãŠã¯äŸ¡å€ããããšæããŸãã
èªç¶ãšäººå·¥ã®äž¡æ¹ã®èšèªã§ãå¹ççã§äœ¿çšããã®ã«é
åçãªãã®ã«ãªãããã«èªç¶ã«é²åããå¿
èŠããããã®ã æçµçã«ã人ã
ã¯èšèªã®åæžã䜿çšããããšã決å®ãïŒ "okay" => "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ã¯ãéçãªx
ã¡ã³ããŒãå¿
èŠã§ããããšãæå®ã§ããå¿
èŠããããŸããããã¯ãã¯ã©ã¹Aãf
ã¡ãœããã§äœ¿çšããããã§ãã
é£çµ¡ãã£ã ïŒ
æ©èœã¯æ¬åœã«å¿
èŠã§ãð
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
vs
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ã¡ãœããã匷å¶çã«å®è£
ããããšæããŸãã
ãã®ãããªåäœãå®è£
ããããã®åé¿çã¯ãããŸããïŒ
ç·šéïŒã³ã³ã¹ãã©ã¯ã¿ãŒãšããŠdeserialize
ã䜿çšããããšãã§ããããšã¯ç¥ã£ãŠããŸãããã¯ã©ã¹ã¯1ã€ã®ã³ã³ã¹ãã©ã¯ã¿ãŒããæãŠãªãããããã¡ã¯ããªã¡ãœãããå¿
èŠã«ãªããŸãã 人ã
ã¯ãã€ã³ã¿ãŒãã§ãŒã¹ã«ãã¡ã¯ããªã¡ãœãããèŠæ±ããæ¹æ³ãæãã§ããŸããããã¯å®å
šã«çã«ããªã£ãŠããŸãã
ãã·ãªã¢ã©ã€ãºãããã¯ã©ã¹ãã®ãã®ã«éçãã·ãªã¢ã©ã€ãºã¡ãœãããã¢ã¿ããããã¡ãªããããªããããåã«desireizationããžãã¯ãå¥ã®ã¯ã©ã¹ã«æã£ãŠãããŸãã
class Deserializer {
deserializeThis(...): Xxx {}
deserializeThat(...): Yyy {}
}
äœãåé¡ã§ããïŒ
@ aleksey-bykovå¥ã®ã¯ã©ã¹ã¯ãããã«èŠããŸãã
@ aleksey-bykovãåé¡ã¯ãã·ãªã¢ã«åãå¿ èŠãªã¯ã©ã¹ãè€æ°ããããšã§ãããã®ãããããªãã®ã¢ãããŒãã¯ãuberclassã¢ã³ããã¿ãŒã³ã§ããã·ãªã¢ã«åå¯èœã®ãã£ã¯ã·ã§ããªãäœæããããšãäœåãªããããŠããããããã®ãããããå€æŽãããã³ã«ããã®uberclassã§ç·šéããå¿ èŠããããŸããããã«ãããã³ãŒãã¯åä»ãªãã®ã«ãªããŸãã ã·ãªã¢ã«åå¯èœãªã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšãããšãç¹å®ã®ãªããžã§ã¯ãã¿ã€ãã«å®è£ ã匷å¶ã§ããããªã¢ãŒãã£ãã¯ç¶æ¿ããµããŒãã§ããŸãããããã人ã ãæãäž»ãªçç±ã§ãã å©çããããã©ãããæšæž¬ããªãã§ãã ããã誰ããéžæè¢ãæã¡ãèªåã®ãããžã§ã¯ãã«ãšã£ãŠäœãæçããéžæã§ããã¯ãã§ãã
@octaharonã¯ããã·ãªã¢ã©ã€ãºå°çšã®ã¯ã©ã¹ãæã£ãŠããã®ã§ãããªããèšã£ãããšãšã¯ãŸã£ããéã§ããå€æŽããã®ã¯ãã·ãªã¢ã©ã€ãºãæ°ã«ãããšãã ããªã®ã§ãåäžè²¬ä»»ããããŸãã
å察ã«ãææ¡ããããã«ã¯ã©ã¹èªäœã«éã·ãªã¢ã«åãè¿œå ãããšãã¯ã©ã¹ã«è¿œå ã®è²¬ä»»ãšå€æŽã®çç±ãè¿œå ãããŸã
æåŸã«ãéçã¡ãœããã«åé¡ã¯ãããŸããããæœè±¡éçã¡ãœãããšéçã€ã³ã¿ãŒãã§ã€ã¹ã®å®éã®ãŠãŒã¹ã±ãŒã¹ã®äŸãèŠãŠæ¬åœã«èå³ããããŸã
@octaharonã¯ããã·ãªã¢ã©ã€ãºå°çšã®ã¯ã©ã¹ãæã£ãŠããã®ã§ãããªããèšã£ãããšãšã¯ãŸã£ããéã§ããå€æŽããã®ã¯ãã·ãªã¢ã©ã€ãºãæ°ã«ãããšãã ããªã®ã§ãåäžè²¬ä»»ããããŸãã
ãã ããïŒéïŒã·ãªã¢ã«åã¯åã®æ§é ã«äŸåãããããã³ãŒãã1ãæã§ã¯ãªã2ãæã§å€æŽããå¿ èŠããããŸãã ããã¯ãåäžè²¬ä»»ãã«ã¯ã«ãŠã³ããããŸãã
å察ã«ãææ¡ããããã«ã¯ã©ã¹èªäœã«éã·ãªã¢ã«åãè¿œå ãããšãã¯ã©ã¹ã«è¿œå ã®è²¬ä»»ãšå€æŽã®çç±ãè¿œå ãããŸã
ããªãã®èšã£ãŠããããšãããããŸããã ç¬èªã®ïŒéïŒã·ãªã¢ã«åãæ åœããã¯ã©ã¹ã¯ããŸãã«ç§ãæãã§ãããã®ã§ãããããæ£ãããééã£ãŠããããæããªãã§ãã ããã
åäžè²¬ä»»ã¯ãé¢ä¿ãããã¡ã€ã«ã®æ°ã«ã€ããŠã¯äœãè¿°ã¹ãŠããããåäžã®çç±ãå¿ èŠã§ãããšè¿°ã¹ãŠããã ãã§ãã
ç§ãèšã£ãŠããã®ã¯ãæ°ããã¯ã©ã¹ãè¿œå ãããšãã¯ãåã«éã·ãªã¢ã«åããã以å€ã®ç®çã§ãããæå³ããã®ã§ããã§ã«ååšããçç±ãšããã«å²ãåœãŠããã責任ããããšããããšã§ãã 次ã«ãããèªäœãéã·ãªã¢ã«åã§ãããšããå¥ã®è²¬ä»»ãè¿œå ããŸããããã«ããã2ã€ã®è²¬ä»»ãçºçããŸããããã¯ãSOLIDã«éåããŸããã¬ã³ããªã³ã°ãå°å·ãã³ããŒã転éãæå·åãªã©ãè¿œå ãç¶ãããšãç¥ã®ã¯ã©ã¹ãååŸããŸãã
ãããŠãç§ãããªãã«å¹³å¡ããèšãã®ãèš±ããŠãã ããããããå©çãšå®éã®ãŠãŒã¹ã±ãŒã¹ã«ã€ããŠã®è³ªåïŒãããŠçãïŒã¯ãã®æ©èœææ¡ãå®è¡ãããããã«é§ãç«ãŠããã®ã§ã
SOLIDã¯ãå šèœã®ç¥ããã¿ãã¬ããã§éä¿¡ããããã®ã§ã¯ãããŸãããéä¿¡ããããšããŠãããã®è§£éã«ã¯ããçšåºŠã®èªç±åºŠããããŸãã ããªãã¯ããã«ã€ããŠããªããæãã®ãšåããããçæ³äž»çŸ©çãããããŸããããç§ã«ãé¡ãããŸãïŒããªãã®ä¿¡å¿µãã³ãã¥ããã£ã«åºããªãã§ãã ããã 誰ããèªåã®å¥œããªæ¹æ³ã§ããŒã«ã䜿çšããèªåãç¥ã£ãŠãããã¹ãŠã®å¯èœãªã«ãŒã«ãç Žããã¹ãŠã®æš©å©ãæã£ãŠããŸãïŒæ®ºäººã®ããã§ãã€ãã責ããããšã¯ã§ããŸããïŒã ããŒã«ã®å質ãå®çŸ©ããã®ã¯ãç¹å®ã®æ©èœã«å¯ŸããéèŠãšãããã«å¯ŸããæäŸãšã®éã®ãã©ã³ã¹ã§ãã ãããŠããã®ãã©ã³ãã¯éèŠã®éã瀺ããŠããŸãã ãã®æ©èœãå¿ èŠãªãå Žåã¯ã䜿çšããªãã§ãã ããã ç§ããããŸãã ãããŠãããã®å€ãã®äººã ããããå¿ èŠãšããŠããŸãããããŠããªããå®éã«ãããç¡èŠããã¹ãã§ãããšããªããèšã£ãŠããéã_we_ã¯å®çšçãªãŠãŒã¹ã±ãŒã¹ãæã£ãŠããŸãã ããã¯ãã¡ã³ããã«ãšã£ãŠããéèŠãªããšãã€ãŸãèãªãååïŒåœŒãããããç解ããæ¹æ³ã«é¢ä¿ãªãïŒããŸãã¯ã³ãã¥ããã£ã«ã€ããŠã®ã¿ã§ãã
ç·ãè¯ãææ¡æ©èœã®ãŠãŒã¹ã±ãŒã¹ã¯ãããŸãããããã¯ããã§ã¯ãããŸãã
ã ããç§ã¯ããã€ãã®å¥œå¥å¿ãè¡šæããŠè³ªåãããŸãããææ¡ã¯ãããè¿°ã¹ãŠããªãã®ã§ããªãããªãã¯ãããå¿ èŠãšãããããããŸãã
ããã¯å žåçãªãã®ã«èŠçŽãããŸãïŒãã åå ãããªãã¯ãããŠããªãã§ãã ãã
å人çã«ç§ã¯åºäœããã£ãšãæ°ã«ããŸãããç§ã¯ã¡ããã©ãã£ãšåã«ããã倧ããããããŸãããããªãã¯ãuberclassã¢ã³ããã¿ãŒã³ãåŒæ°ãæããããšã«ãã£ãŠãããæã¡åºãããããŠããã®è§£éãžã®èªç±åºŠãã«ããã¯ã¢ããããŸãã
ãã®ãã£ã¹ã«ãã·ã§ã³å šäœã§èšåãããŠããå¯äžã®å®éçãªçç±ã¯æ¬¡ã®ãšããã§ãïŒ 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
ãªã©ãæã£ãŠã¯ãããªãã®ãã瀺ããŠããŸããïŒ
ãªãããã圹ç«ã€ã®ãã瀺ãææ¡ããã£ãšãããŸããïŒ
ãããããç§ãã¡ã¯ç©äºãå·»ã蟌ã¿ãè°è«ãããããšãèŠçŽããå¿ èŠããããŸããããããã°ã解決çãèŠã€ããããšãã§ããŸãã
ç§ãç解ããŠããããã«ã2ã€ã®ææ¡ããããŸãã
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ã«ã€ããŠã¯ãæè¡çã«ã¯åé¿çããããŸãã ããã¯çŽ æŽãããããšã§ã¯ãããŸããããå°ãªããšãããã¯äœãã§ãã ãã ããããã¯åé¿çã§ãã
ã€ã³ã¿ãŒãã§ã€ã¹ã2ã€ã«åå²ããŠã次ã®ããã«ã¯ã©ã¹ãæžãçŽãããšãã§ããŸãã
interface StaticInterface {
new(...args) => MyClass;
fromJson(json): MyClass;
}
interface InstanceInterface {
toJson(): string;
}
const MyClass: StaticInterface = class implements InstanceInterface {
...
}
ç§ã®æèŠã§ã¯ãããã¯å€ãã®äœåãªäœæ¥ã§ãããå°ãèªã¿ã«ãããã¯ã©ã¹ãé¢çœãæ¹æ³ã§æžãçŽããšããæ¬ ç¹ããããŸããããã¯åã«å¥åŠã§ã䜿çšããŠããæ§æããéžè±ããŠããŸãã
ã§ã¯ãææ¡2ã«ã€ããŠã¯ã©ãã§ããããã ããã«ã€ããŠã§ããããšã¯äœããããŸãããã ããã察åŠãã䟡å€ããããšæããŸãïŒ
ãããã®ã¿ã€ãã®1ã€ã®å®éã®äœ¿çšæ³ã¯äœã§ããïŒãããã®1ã€ã¯ã©ã®ããã«äœ¿çšãããŸããïŒ
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ã¡ãœããã®æå¹ãªãŠãŒã¹ã±ãŒã¹ã1ã€ãããŸããããã«ã€ããŠã§ãã
@ 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
ã§ããïŒãŠãŒã¶ãŒã¯åãïŒããããæœè±¡ïŒèŠªã®ãµãã¯ã©ã¹ãäœæããŸãã©ã€ãã©ãªããã®ã¯ã©ã¹ã
ããã§ãæåŸã®ãã©ã¡ãŒã¿ãŒããªãã·ã§ã³ãªããžã§ã¯ãã«ãªãããã«ããã®ã³ã³ãã©ã¯ããå€æŽããå¿
èŠããããŸãã 3çªç®ã®åŒæ°ã«æååå€ãæž¡ãããšã¯å埩äžèœãªãšã©ãŒã§ãããã³ã³ãã€ã«æã«ãã©ã°ãç«ãŠãå¿
èŠããããŸãã foo
ãåŒã³åºããšãã«ã代ããã«ãªããžã§ã¯ããæž¡ãããã«ãã¡ã¯ããªã¯ã©ã¹ãæŽæ°ããå¿
èŠããããŸãããŸãã foo
ãå®è£
ãããµãã¯ã©ã¹ã¯ãåŒã³åºãã·ã°ããã£ãå€æŽããå¿
èŠããããŸãã
æ°ããã©ã€ãã©ãªããŒãžã§ã³ã«æŽæ°ãããŠãŒã¶ãŒããã³ã³ãã€ã«æã«é倧ãªå€æŽããã£ããããããšãä¿èšŒããããšæããŸãã ã©ã€ãã©ãªã¯ãäžèšã®éçã€ã³ã¿ãŒãã§ã€ã¹ã®åé¿çã®1ã€ïŒ type MyClass = (new (data: number[]) => MyInterface) & MyStaticInterface;
ãªã©ïŒããšã¯ã¹ããŒãããå¿
èŠããããã³ã³ã·ã¥ãŒããŒãããããã¹ãŠã®é©åãªå Žæã«é©çšããããšãæåŸ
ããŸãã å®è£
ã®1ã€ãè£
食ããã®ãå¿ããå ŽåããŸãã¯ã©ã€ãã©ãªã®ãšã¯ã¹ããŒããããåã䜿çšããŠãã¡ã¯ããªã¯ã©ã¹ã®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
å¶çŽã¯åé¡ãæ©æã«ãã£ããããæå³ãæ確ã«ããŸãã
ç§ã¯ããªãã®ããµã€ãããŒããã®æžå¿µã«åããªããšæãå¥ã®äŸããããŸãã ããã³ããšã³ããããžã§ã¯ãã«ã¯ããã€ãã®å
åŒã¯ã©ã¹ããããç¹å®ã®æ©èœã«äœ¿çšããããããã€ããŒãããŠãŒã¶ãŒã«éžæãããããšãã§ããŸãã ãã¡ããã 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; }
å¥ã®ãŠãŒã¹ã±ãŒã¹ïŒçæãããã³ãŒã/éšåçãªã¯ã©ã¹ã·ã
import
ã¹ããŒãã¡ã³ããæçµçãªããŒãžã§ç¡èŠãããããã«æå®ããŠãæçµçã«çæãããã³ãŒãã§ãshimãã€ã³ã¯ã«ãŒããç¡èŠãããããã«ããããšãã§ããŸããinterface SwaggerException
{
static isSwaggerException(obj: any): obj is SwaggerException;
}
ããããç§ã¯ãããè¡ãããšãã§ãããå®éã«ã¯ã©ã¹ãäœæããå¿ èŠããããŸããããã¯åé¡ãããŸããããããã§ãééã£ãŠãããšæããŸãã ä»ã®å€ãã®äººãèšã£ãŠããããã«ããããã¯å¥çŽã§ãããšèšãããã ãã§ãã
ã³ãŒãçæã«ã€ããŠä»ã«èšåãããŠããªãã®ã§ãããã«ãããè¿œå ãããã£ãã ãã§ãããå€ãã®ããªããããå¿ èŠãªã®ãããšããã³ã¡ã³ãã¯ã€ã©ã€ã©ããŸãã ã€ã³ã¿ãŒãã§ãŒã¹ã§ãã®ãéçãæ©èœããå¿ èŠãšããŠããã人ã ã®ããªãã®å²åããå€éšã®ã©ã€ãã©ãªé ç®ãåç §ã§ããããã«ããããã ãã«ãããè¡ã£ãŠãããšæããŸãã
ãŸããç§ã¯æ¬åœã«ããã¯ãªãŒã³ãªd.ts
ãã¡ã€ã«ãèŠãããšæã£ãŠããŸã-ãã®æ©èœãšãããã®ãã¡ã€ã«ãšã®éè€ãå¿
èŠã§ãã JQueryStaticã®ãããªãã®ã¯ãåãªãããã¯ã®ããã«èŠãããããç解ããã®ã¯å°é£ã§ãã ãŸããçŸå®ã«ã¯ã d.ts
ãã¡ã€ã«ã¯å€ããç¶æãããŠããªãããšãå€ããèªåã§ã·ã ã宣èšããå¿
èŠããããŸãã
ïŒ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;
}
ç§ã¯ãã®ã¹ã¬ãããããããèµ€ãããŸãããããªããã®ãã¿ãŒã³ã«ããŒãšèšãã®ãè¯ãã®ãæ£ããã®ããŸã ããããŸããã ããªãããã®æèŠãå ±æãããªããããªãã¯ãŸããJavaãä»ã®äººæ°ã®ããèšèªããããééã£ãŠãããšèšããŸãã ãŸãã¯ç§ã¯ééã£ãŠããŸããïŒ
ãã®å·ã¯2幎éå
¬éãããŠããã79件ã®ã³ã¡ã³ãããããŸãã Awaiting More Feedback
ãšããã©ãã«ãä»ããŠããŸãã 決å®ãäžãããã«å¿
èŠãªä»ã®ãã£ãŒãããã¯ãæããŠãã ããã
ã€ã³ã¿ãŒãã§ã€ã¹ã§ãæœè±¡ã¯ã©ã¹ã§ãéçã¡ãœãããèšè¿°ã§ããªãã®ã¯æ¬åœã«è¿·æã§ãïŒå®£èšã®ã¿ïŒã ãã®æ©èœã¯ãŸã å®è£ ãããŠããªããããåé¿çãæžãã®ã¯ãšãŠãéãã§ã=ïŒ
ããšãã°ãnext.jsã¯ãéçãªgetInitialProps
é¢æ°ã䜿çšããŠãããŒãžãäœæããåã«ããŒãžã®ããããã£ãååŸããŸãã ã¹ããŒãããå ŽåãããŒãžã¯äœæãããŸãããããšã©ãŒããŒãžãäœæãããŸãã
https://github.com/zeit/next.js/blob/master/packages/next/README.md#fetching -data-and-component-lifecycle
ãã ããæ®å¿µãªããããã®ã¡ãœãããå®è£ ããæãããã¯ãåãã§ãã¯ãã§ããªããããå®è¡æã«ãšã©ãŒãçºçããå Žåã§ããä»»æã®åã·ã°ããã£ãäžããããšãã§ããŸãã
ãã®åé¡ã¯ããã«é·ãéååšããŠãããšæããŸãããããã¯JavaScriptèªäœãéçãªãã®ãåŸæã§ã¯ãªãããã§ãð€
éçç¶æ¿ã¯ãããããååšããŠã¯ãªããŸããã ð€ð€
éçã¡ãœãããåŒã³åºããããéçãã£ãŒã«ããèªã¿åã£ãããããã®ã¯èª°ã§ããïŒ ð€ð€ð€
ä»ã«ãŠãŒã¹ã±ãŒã¹ã¯ãããŸããïŒð€ð€ð€ð€
ããã«é¢ããæŽæ°ã¯ãããŸããïŒ
ãããå©ãã«ãªããªããã¯ã©ã¹ã®éçã€ã³ã¿ãŒãã§ãŒã¹ãå ¥åããå¿ èŠãããå Žåã«ç§ãããããšã¯ããã³ã¬ãŒã¿ã䜿çšããŠã¯ã©ã¹ã«éçã¡ã³ããŒã匷å¶ããããšã§ã
ãã³ã¬ãŒã¿ã¯æ¬¡ã®ããã«å®çŸ©ãããŸãã
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
ã¯ã¯ã©ã¹å®çŸ©å°çšã®æ°ããçš®é¡ã®æœè±¡åã·ã³ãã«ã«ãªããŸãã
éèŠã§ã¯ãªãå°ããªãŠãŒã¹ã±ãŒã¹ããã1ã€ãããŸãã
Angular for AOTã³ã³ãã€ã«ã§ã¯ããã³ã¬ãŒã¿ã§é¢æ°ãåŒã³åºãããšã¯ã§ããŸããïŒ @NgModule
ã¢ãžã¥ãŒã«ãã³ã¬ãŒã¿ã®ããã«ïŒ
è§åºŠã®åé¡
Service Workerã¢ãžã¥ãŒã«ã®å Žåã次ã®ãããªãã®ãå¿
èŠã§ãã
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ã¯èšåããè©«ã³ããŸããããã®æ©èœã®ææ¡ã¯ãã³ãã¥ããã£ããå€ãã®ãµããŒããåããŠãããå®è£ ã¯ããªãç°¡åã ãšæããŸãããIssuesã«ããŽãªã®å¥¥æ·±ãã«åãããŠããããã§ãã ãã®æ©èœã«ã€ããŠã³ã¡ã³ãã¯ãããŸããïŒ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ãæ¡åŒµããå¿ èŠããããŸãã å®éã«ã³ã³ã¹ãã©ã¯ã¿ãŒèªäœã«ã¡ãœãããã¢ã¿ããããå Žåã¯ãã€ã³ã¹ã¿ã³ã¹ã¡ãœããã宣èšããŸãã ããã¯ã宣èšã®ããŒãžã«ãã£ãŠãã§ã«å¯èœã ãšæããŸãã
`` `` ts
ã°ããŒãã«ã宣èšãã{
ã€ã³ã¿ãŒãã§ã€ã¹ObjectConstructor {
helloïŒïŒïŒæåå;
}
}
Object.helloïŒïŒ;
`` ``
@ thw0rtedãã°ãããïŒ ObjectConstructorãç¥ããªãã£ãããããšã
ãã倧ããªãã€ã³ãã¯ãã€ã³ã¹ã¿ã³ã¹åã§ã¯ãªãã³ã³ã¹ãã©ã¯ã¿åãæ¡åŒµããŠãããšããããšã§ãã lib.es5.d.ts
ã®Object
宣èšã調ã¹ããšãããã¿ã€ããObjectConstructor
ã§ããããšãããããŸããã
ãã®åé¡ããŸã æ®ã£ãŠãããšã¯ä¿¡ããããã§ãã ããã¯åæ³çã«åœ¹ç«ã€æ©èœã§ãããããã€ãã®å®éã®äœ¿çšäŸããããŸãã
TypeScriptã®èŠç¹ã¯ãã³ãŒãããŒã¹ã§åã®å®å šæ§ã確ä¿ã§ããããã«ããããšã§ããããã§ã¯ããªããã®æ©èœã¯2幎åã®ãã£ãŒãããã¯ã®åŸãããã£ãŒãããã¯ãä¿çãããŠããã®ã§ããããã
ç§ã¯ããã«ã€ããŠã¯ããªãé ããããããŸããããPythonã®ã¡ã¿ã¯ã©ã¹ãã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ã®ææ¡ã«å°ã䌌ãŠããŸãããå¥åã®çš®é¡ã®ã€ã³ã¿ãŒãã§ãŒã¹ããããŸããã ããã§ã¯ãã€ã³ã¿ãŒãã§ãŒã¹ã®æŠå¿µã1ã€ããããããã䜿çšããŠã€ã³ã¹ã¿ã³ã¹ãŸãã¯ã¯ã©ã¹ã®åœ¢ç¶ãèšè¿°ããããšãã§ããŸãã å®è£ ã¯ã©ã¹å®çŸ©ã®ããŒã¯ãŒãã¯ãåã€ã³ã¿ãŒãã§ã€ã¹ãã©ã¡ãåŽã§ãã§ãã¯ããããã³ã³ãã€ã©ã«æ瀺ããŸãã
ç®çã®æ©èœã«å¿ããŠãïŒ34516ãšïŒ33892ã§ãã£ã¹ã«ãã·ã§ã³ãåãäžããŸãããã
æãåèã«ãªãã³ã¡ã³ã
Serializableã®ãµãã¯ã©ã¹ã«éçdeserializeã¡ãœããã匷å¶çã«å®è£ ããããšæããŸãã
ãã®ãããªåäœãå®è£ ããããã®åé¿çã¯ãããŸããïŒ