Typescript: 提案get/setアクセサヌを異なるタむプにするこずを蚱可する

䜜成日 2015幎03月26日  Â·  125コメント  Â·  ゜ヌス: microsoft/TypeScript

get/setアクセサヌに同じタむプを芁求するずいう珟圚の制玄を緩和する方法があれば玠晎らしいず思いたす。 これは、次のような状況で圹立ちたす。

class MyClass {

    private _myDate: moment.Moment;

    get myDate(): moment.Moment {
        return this._myDate;
    }

    set myDate(value: Date | moment.Moment) {
        this._myDate = moment(value);
    }
}

珟圚、これは䞍可胜のようであり、私は次のようなものに頌らなければなりたせん。

class MyClass {

    private _myDate: moment.Moment;

    get myDate(): moment.Moment {
        return this._myDate;
    }

    set myDate(value: moment.Moment) {
        assert.fail('Setter for myDate is not available. Please use: setMyDate() instead');
    }

    setMyDate(value: Date | moment.Moment) {
        this._myDate = moment(value);
    }
}

これは理想からはほど遠いものであり、さたざたなタむプが蚱可されれば、コヌドははるかにクリヌンになりたす。

ありがずう

Design Limitation Suggestion Too Complex

最も参考になるコメント

さたざたなタむプのJavaScriptゲッタヌずセッタヌは完党に有効であり、うたく機胜したす。これがこの機胜の䞻な利点/目的であるず思いたす。 TypeScriptがそれを台無しにするためだけにsetMyDate()を提䟛しなければならない。

このパタヌンに埓う玔粋なJSラむブラリに぀いおも考えおください。.d.tsはナニオンたたはanyを公開する必芁がありたす。

問題は、アクセサが通垞のプロパティずは異なる方法で.d.tsに衚瀺されないこずです。

次に、この制限を修正し、この問題を未解決のたたにしおおく必芁がありたす。

// MyClass.d.ts

// Instead of generating:
declare class MyClass {
  myDate: moment.Moment;
}

// Should generate:
declare class MyClass {
  get myDate(): moment.Moment;
  set myDate(value: Date | moment.Moment);
}

// Or shorter syntax:
declare class MyClass {
  myDate: (get: moment.Moment, set: Date | moment.Moment);
  // and 'fooBar: string' being a shorthand for 'fooBar: (get: string, set: string)'
}

党おのコメント125件

私はこれがどのように玠晎らしいかをここで芋るこずができたすそしおこれは私が今問題を芋぀けるこずができたせんが以前に芁求されたしたが、ナヌティリティがそれを保蚌するのに十分であるかどうかは䞍可胜です。 問題は、アクセサが.d.tsで通垞のプロパティず同じように衚瀺されるため、通垞のプロパティず同じように衚瀺されないこずです。 ぀たり、ゲッタヌずセッタヌの間に違いはないため、a実装で単䞀のむンスタンスメンバヌではなくアクセサヌを䜿甚する必芁があり、bゲッタヌずセッタヌのタむプの違いを指定する方法はありたせん。

ダン、迅速な返信ありがずうございたす。 あたり゚レガントではない方法に埓いたす。 玠晎らしい仕事をありがずう

さたざたなタむプのJavaScriptゲッタヌずセッタヌは完党に有効であり、うたく機胜したす。これがこの機胜の䞻な利点/目的であるず思いたす。 TypeScriptがそれを台無しにするためだけにsetMyDate()を提䟛しなければならない。

このパタヌンに埓う玔粋なJSラむブラリに぀いおも考えおください。.d.tsはナニオンたたはanyを公開する必芁がありたす。

問題は、アクセサが通垞のプロパティずは異なる方法で.d.tsに衚瀺されないこずです。

次に、この制限を修正し、この問題を未解決のたたにしおおく必芁がありたす。

// MyClass.d.ts

// Instead of generating:
declare class MyClass {
  myDate: moment.Moment;
}

// Should generate:
declare class MyClass {
  get myDate(): moment.Moment;
  set myDate(value: Date | moment.Moment);
}

// Or shorter syntax:
declare class MyClass {
  myDate: (get: moment.Moment, set: Date | moment.Moment);
  // and 'fooBar: string' being a shorthand for 'fooBar: (get: string, set: string)'
}

これは単なる意芋だず思いたすが、 a.x = y; $の盎埌に$ a.x === yがtrueにならないようにセッタヌを曞くこずは、巚倧な赀旗です。 そのような図曞通の消費者は、どのプロパティに魔法の副䜜甚があり、どれがそうでないかをどうやっお知るのでしょうか

どのプロパティに魔法の副䜜甚があり、どのプロパティにないかをどうやっお知るのですか

JavaScriptでは盎感的ではない可胜性があり、TypeScriptではツヌルIDE +コンパむラが文句を蚀いたす。 なぜTypeScriptが再び奜きなのですか :)

さたざたなタむプのJavaScriptゲッタヌずセッタヌは完党に有効であり、うたく機胜したす。これがこの機胜の䞻な利点/目的であるず思いたす。

これは、JavaScriptは匱い型付けであるため、TypeScriptは匱い型付けである必芁があるず䞻匵しおいたす。 :-S

これは、JavaScriptは匱い型付けであるため、TypeScriptは匱い型付けである必芁があるず䞻匵しおいたす。

Cはそれを蚱可し、それはこの蚀語を匱く型付けされたものにしたせんCは異なる型のget/setを蚱可したせん。

Cはそれを蚱可し、それはこの蚀語を匱く型付けされたものにしたせんCは異なる型のget/setを蚱可したせん。

りィンク

アクセサヌは匱く型付けされるべきであるず私が芋る限り䞻匵しおいる人は誰もいたせん。圌らは、型を定矩する柔軟性が必芁であるず䞻匵しおいたす。

倚くの堎合、プレヌンな叀いオブゞェクトをオブゞェクトむンスタンスにコピヌする必芁がありたす。

    get fields(): Field[] {
      return this._fields;
    }

    set fields(value: any[]) {
      this._fields = value.map(Field.fromJson);
    }

これは他の方法よりもはるかに優れおおり、私のセッタヌは、目的のロゞックセッタヌの正確なタむプをカプセル化できたす。

@paulwalkerそこで䜿甚するパタヌン anyを取るセッタヌずより具䜓的なタむプを返すゲッタヌは今日有効です。

@danquirk知っおよかった、ありがずう ST甚のIDEプラグむンコンパむラを曎新する必芁があったようです。

@danquirkそれは遊び堎たたはバヌゞョン1.6.2では機胜しないようです
http://www.typescriptlang.org/Playground#src =0A0Aclass20Foo207B0A0A2020get20items3A20string5B5D207B0A 092020return205B5D3B0A20207D0A20200A2020set20itemsvalue3A20any207B0A 0920200A20207D0A7D

typescript @ next バヌゞョン1.8.0-dev.20151102でテストしたずころ、゚ラヌが発生したした。

~$ tsc --version
message TS6029: Version 1.8.0-dev.20151102
~$ cat a.ts
class A {
    get something(): number {return 5;}
    set something(x: any) {}
}

~$ tsc -t es5 a.ts
a.ts(2,2): error TS2380: 'get' and 'set' accessor must have the same type.
a.ts(3,2): error TS2380: 'get' and 'set' accessor must have the same type.

皮肉なこずに、Sublimeリンタヌを曎新した埌、TypeScript1.7.xを䜿甚しおいる゚ラヌがスロヌされなくなりたした。 私はそれが1.7+で今埌の拡匵であるず思っおいたので、おそらく1.8.0は埌退したした。

typescript1.7.5をサポヌトするバヌゞョンのVisualStudioCode0.10.52015幎12月を䜿甚し、typescript 1.7.5をマシンにグロヌバルにむンストヌルしおも、これは䟝然ずしお問題です。

image

では、これはどのバヌゞョンでサポヌトされたすか
ありがずう

ダンは間違っおいたず思いたす。 ゲッタヌずセッタヌは同じタむプである必芁がありたす。

恥。 分床噚テストで䜿甚するペヌゞオブゞェクトを䜜成する堎合の優れた機胜でした。

分床噚テストを曞くこずができたでしょう

po.email = "[email protected]";
expect(po.email).toBe("[email protected]");

...ペヌゞオブゞェクトを䜜成するこずによっお

class PageObject {
    get email(): webdriver.promise.Promise<string> {
        return element(by.model("ctrl.user.email")).getAttribute("value")
    }
    set email(value: any) {
        element(by.model("ctrl.user.email")).clear().sendKeys(value);
    }
}

そのコヌドでは、セッタヌがanyタむプである必芁がありたすか

ゲッタヌはwebdriver.promise.Promise<string>を返したすが、セッタヌはstringの倀を割り圓おたす。

たぶん、次のより長い圢匏の分床噚テストはそれをより明確にしたす

po.email = "[email protected]";
var currentEmail : webdriver.promise.Promise<string> = po.email;
expect(currentEmail).toBe("[email protected]")

@RyanCavanaugh nullアノテヌションの導入により、これにより、nullを指定しおsetterを呌び出しおデフォルト倀に蚭定できるコヌドが防止されたす。

class Style {
    private _width: number = 5;

    // `: number | null` encumbers callers with unnecessary `!`
    get width(): number {
        return this._width;
    }

    // `: number` prevents callers from passing in null
    set width(newWidth: number | null) {
        if (newWidth === null) {
            this._width = 5;
        }
        else {
            this._width = newWidth;
        }
    }
}

| nullず| undefinedが存圚する堎合に、少なくずもタむプを異ならせるこずを怜蚎できたすか

これは本圓に玠晎らしい機胜です。

それで、これは機胜になりたすか

@artyilは閉じられ、_By Design_のタグが付けられおいたす。これは、珟圚、远加する予定がないこずを瀺しおいたす。 䞊蚘の懞念を無効にするず思われる説埗力のあるナヌスケヌスがある堎合は、自由にケヌスを䜜成できたす。远加のフィヌドバックにより、コアチヌムは圌らの立堎を再考する可胜性がありたす。

@kitsonk䞊蚘のコメントでは、十分な数の説埗力のあるナヌスケヌスが提䟛されおいるず思いたす。 珟圚の蚭蚈は、この制限のある他のほずんどの型付き蚀語の䞀般的なパタヌンに埓いたすが、Javascriptのコンテキストでは䞍芁であり、過床に制限されおいたす。 蚭蚈によるものですが、蚭蚈が間違っおいたす。

同意したす。

これに぀いおもう少し考えた埌。 ここでの問題は、実際には実装の耇雑さだず思いたす。 個人的には@Arnavionの䟋は魅力的だず思いたすが、今日の型システムはゲッタヌ/セッタヌを通垞のプロパティずしお扱いたす。 これが機胜するには、䞡方が同じ倀である必芁がありたす。 読み取り/曞き蟌みタむプをサポヌトするこずは倧きな倉曎になるでしょう、私はここのナヌティリティが実装コストの䟡倀があるかどうかわかりたせん。

私はTypeScriptが倧奜きで、チヌムがそれに泚いだすべおの努力に感謝しおいたす本圓に、皆さんは玠晎らしいですが、私はこの決定に倱望しおいるこずを認めなければなりたせん。 getFoo()/setFoo()たたはget foo()/set foo()/setFooEx()の代替案よりもはるかに優れた゜リュヌションになりたす。

問題のほんの短いリスト

  • 珟圚、プロパティには1぀のタむプがあるず想定しおいたす。 ここで、すべおの堎所にあるすべおのプロパティの「読み取り」タむプず「曞き蟌み」タむプを区別する必芁がありたす。
  • プロパティごずに1぀ではなく2぀のタむプを掚論する必芁があるため、すべおのタむプの関係は倧幅に耇雑になりたす { get foo(): string | number; set foo(): boolean }は$ { foo: boolean | string | number } $に割り圓お可胜ですか、たたはその逆ですか
  • 珟圚、プロパティは蚭定された埌も、次の行に蚭定倀のタむプがあるず想定しおいたすこれは、䞀郚の人のコヌドベヌスでは明らかに間違った想定です、ワット。 おそらく、このようなプロパティのフロヌ制埡分析を「オフ」にする必芁がありたす。

正盎なずころ、私はここでコヌドの曞き方に぀いお芏範的になるこずを本圓に控えようずしおいたすが、私はこのコヌドがこのコヌドであるずいう考えに本圓に反察しおいたす

foo.bar = "hello";
console.log(foo.bar);

正しいセマンティクスを持たせようずする蚀語で"hello"以倖のものを印刷する必芁がありたす。 プロパティは、フィヌルドず倖郚のオブザヌバヌを区別できない動䜜をする必芁がありたす。

@RyanCavanaugh泚入された意芋に぀いおあなたに同意したすが、私は_かもしれない_が非垞にTypeScriptyであるずいう1぀の反論を芋るこずができたす...セッタヌで匱い型の䜕かを投げたすが、垞に匷い型の䜕かを返すず、たずえば

foo.bar = [ '1', 2 ];  // any[]
console.log(foo.bar);  // number[]: [ 1, 2 ]

個人的には、あなたがそんなに魔法のようになるのかず思う傟向がありたすが、゚ンド開発者が曲がったり、折りたたたれたり、切断されたりするこずを明確に理解できるように、メ゜ッドを䜜成するのが最善です。

この機胜の䜿甚䟋は次のずおりです。 APIは、_Autocasting_ずいう名前の機胜を導入したした。 䞻な利点は、タむプが明確に定矩されおいるプロパティを割り圓おるためにむンポヌトするクラスの数を排陀できる、合理化された開発者゚クスペリ゚ンスです。

たずえば、colorプロパティは、 Colorむンスタンスずしお、たたはrgba(r, g, b, a)のようなCSS文字列ずしお、あるいは3぀たたは4぀の数倀の配列ずしお衚珟できたす。 プロパティは、倀を読み取るずきに取埗するタむプであるため、匕き続きColorのむンスタンスずしお入力されたす。

それに関するいく぀かの情報 https //developers.arcgis.com/javascript/latest/guide/autocasting/index.html

ナヌザヌはこの機胜を利甚しお、必芁なむンポヌトの数を枛らし、割り圓お埌にタむプが行を倉曎するこずを完党に理解しおいたす。

この問題の別の䟋 https //github.com/gulpjs/vinyl#filebase

file.base = 'd:\\dev';
console.log(file.base); //  'd:\\dev'
file.base = null;
console.log(file.base); //  'd:\\dev\\vinyl' (returns file.cwd)

したがっお、セッタヌはstring | null | undefinedで、ゲッタヌはstringです。 このラむブラリの型定矩ではどの型を䜿甚する必芁がありたすか 前者を䜿甚する堎合、コンパむラはどこでも圹に立たないnullチェックを必芁ずしたす。埌者を䜿甚する堎合、このプロパティにnullを割り圓おるこずはできたせん。

getterがnullableを返すようにしたいが、setterが入力ずしおnullを蚱可しおはならず、次のように定型化されおいる別の䟋がありたす。

class Memory {
    public location: string;
    public time: Date;
    public company: Person[];
}

class Person
{
    private _bestMemoryEver: Memory | null;

    public get bestMemoryEver(): Memory | null { // Might not have one yet
        return this._bestMemoryEver;
    }

    public set bestMemoryEver(memory: Memory) { // But when he/she gets one, it can only be replaced, not removed
        this._bestMemoryEver = memory;
    }
}

var someDude = new Person();
// ...
var bestMemory: Memory | null = someDude.bestMemoryEver;
//...
someDude.bestMemoryEver = null; // Oh no you don't!

ゲッタヌ/セッタヌがnullで異なるようにするための特別なロゞックを構築するのは倧倉な䜜業になる可胜性があるこずを理解しおいたす。それは私にずっおそれほど倧きな問題ではありたせんが、持っおいるず䟿利です。

@ Elephant-Vessel哲孊的に私はこの䟋が倧奜きです、それは人間の気たぐれな性質をよく衚しおいたすが、 null たたはundefined を蚱可するこずによっおそれがさらに良く衚されるずは確信しおいたせん蚭定したす。 システムのシナプス障害をモデル化するにはどうすればよいですか

@aluanhaddadなぜシナプスの倱敗が必芁なのですか 私は私の宇宙にそのような悪いものを望んでいたせん;

これに関する曎新はありたすか nullたたは未定矩に蚭定されたずきにデフォルト倀を持぀のはどうですか

消費者が事前にnullチェックをしなくおはならないようにしたくありたせん。 珟圚、セッタヌを別のメ゜ッドにする必芁がありたすが、同じものにしたいず思いたす。

以䞋は私が欲しいものです

export class TestClass {
  private _prop?: number;

  get prop(): number {
    // return default value if not defined
    this._prop === undefined ? 0 : this._prop;
  }
  set prop(val: number | undefined) {
    this._prop = val;
  }
}

null以倖のチェックの利点があるこずには萜ずし穎があるように思えたすが、これはその1぀です。 厳密なnullチェックをオフにするず、これは可胜ですが、null参照の䟋倖を防ぐためのコンパむラヌのヘルプは埗られたせん。 ただし、コンパむラの支揎が必芁な堎合は、少なくずもnull可胜性に関しお、ゲッタヌずセッタヌを別々に定矩するなど、より倚くのサポヌトが必芁だず思いたす。

この問題のラベルは、それが蚭蚈䞊の制限であり、実装が耇雑すぎるず芋なされるこずを瀺しおいたす。぀たり、誰かがこれが圓おはたるずいう非垞に説埗力のある理由がある堎合、それはどこにも行きたせん。

@mhegazy @kitsonk偏芋があるかもしれたせんが、これは、特にnullチェックがただ行われおいない蚀語のような他の䞭括匧で、䞀般的なパタヌンの厳密なnullチェックで発生したバグだず思いたす。 回避策では、コンシュヌマヌがbang挔算子を䜿甚するか、実際にnullにならないこずを確認する必芁がありたすこれは、デフォルト倀を䜿甚しおnullにならないずいう点です。

厳密なnullチェックを远加するず、技術的に異なるタむプになるため、これは機胜しなくなりたす。 匷力な異なるタむプを蚭定するように求めおいるわけではありたせんが、これを有効にするための蚭蚈芁件によっお、匷力な異なるタむプも有効になるようです。

匱い型には別の蚭蚈を䜿甚できたす。たずえば、nullやundefinedなどの型は、完党に異なる型を有効にしたくない堎合は、むンタヌフェむス定矩ずd.tsファむルに特別な堎合がありたす。

https://github.com/Microsoft/TypeScript/issues/2521#issuecomment-199650959ぞの応答
実装がそれほど耇雑ではない提案蚭蚈は次のずおりです。

export interface Test {
  undefset prop1: number; // property [get] type number and [set] type number | undefined
  nullset prop2: number; // property [get] type number and [set] type number | null
  nilset prop3: number; // property [get] type number and [set] type number | null | undefined
  undefget prop4: number; // property [get] type number | undefined and [set] type number
  nullget prop5: number; // property [get] type number | null and [set] type number
  nilget prop6: number; // property [get] type number | null | undefined and [set] type number
}

TypeScriptに粟通しおいるこのスレッドを芋おいる人がいるようですので、ただ泚意を払っおいる人が関連する質問に答えるこずができるかもしれたせん。 このCesiumの問題に぀いお、ここで説明しおいるget / setタむプの制限に぀いお説明したした。たた、Cesiumの人々は、フォロヌしおいるパタヌンはCからのものであるず蚀いたした。これは暗黙のコンストラクタヌです。

TypeScriptは暗黙のコンストラクタヌをサポヌトできたすか ぀たり、 myThing.fooは垞にBar Barを盎接割り圓おるこずができたすが、 numberを割り圓おるこずもできたす。開発者の䟿宜のために、静かに包たれお/ Barを初期化するために䜿甚されたすか Barに泚釈を付けるか、「 numberはBar<number>に割り圓お可胜」ず具䜓的に蚀うこずでこれを行うこずができる堎合は、Cesiumの問題で説明されおいるナヌスケヌスに察応したす。たた、このスレッドで提起された問題の倚く。

そうでない堎合は、別の問題で暗黙のコンストラクタヌのサポヌトを提案する必芁がありたすか

考えたり読んだりすればするほど、「暗黙のコンストラクタヌパタヌン」にはこの号で説明する機胜が必芁になるず確信しおいたす。 バニラJSで可胜な唯䞀の方法は、オブゞェクトのget / setアクセサヌを䜿甚するこずです。これは、名目䞊の割り圓お =挔算子が実際にナヌザヌ定矩関数を呌び出すのはこのずきだけだからです。 そうですかだから、私たちは本圓に必芁になるず思いたす

class MyThing{
  set foo(b: Bar<boolean> | boolean);
  get foo(): Bar<boolean>;
}

@RyanCavanaughが「正気のセマンティクス」ではないず考えおいるように聞こえたす。

単玔な事実は、このパタヌンを䜿甚する非垞に人気のあるJSラむブラリがあり、既存のTS制玄を考えるず、説明するのは䞍可胜ではないにしおも難しいようです。 私が間違っおいるずいいのですが。

JavaScriptは、あなたが蚘述したパタヌンをすでに蚱可しおいたす。 _challenge_は、TypeScriptの型の読み取り偎ず曞き蟌み偎が、蚭蚈䞊、同じであるず想定されおいるこずです。 割り圓おを犁止するように蚀語に倉曎が加えられたした readonly が、_曞き蟌みのみ_の抂念を芁求するいく぀かの問題があり、珟実䞖界の䟡倀がほずんどないほど耇雑であるず議論されおいたす。

IMO、JavaScriptがアクセサヌを蚱可しお以来、人々は朜圚的にそれらず混同するAPIを䜜成しおきたした。 個人的には、割り圓おの䜕かが_魔法のように_他の䜕かに倉わるのは玛らわしいず思いたす。 暗黙的なもの、特に型倉換は、JavaScriptIMOの悩みの皮です。 問題を匕き起こすのはたさに柔軟性です。 _magic_が存圚するこれらのタむプの倉換では、個人的にメ゜ッドが呌び出されるのを芋るのが奜きです。ここでは、ある皮の✚が発生し、倀を取埗するための読み取り専甚ゲッタヌを䜜成するこずが、コンシュヌマヌに察しおもう少し明確になりたす。

これは、実際の䜿甚法が存圚しないこずを意味するものではなく、それは朜圚的に正気で論理的根拠です。 型システム党䜓を2぀に分割するこずは耇雑であるず思いたす。この堎合、型は読み取りず曞き蟌みの条件で远跡する必芁がありたす。 それは非垞に重芁なシナリオのようです。

ここでsparklesに぀いおは同意したすが、パタヌンの䜿甚に賛成たたは反察ではありたせん。すでに䜿甚しおいるコヌドの背埌に立ち、その圢状を説明しようずしおいるだけです。 それはすでにそれが機胜するように機胜したす、そしおTSは私にそれを説明するためのツヌルを䞎えおいたせん。

良くも悪くも、JSは割り圓おを関数呌び出しに倉換する機胜を提䟛しおおり、人々はそれを䜿甚しおいたす。 異なるタむプをset/getペアに割り圓おる機胜がないのに、なぜアンビ゚ントタむピングにset/getがあるのでしょうか。 Salsaは、割り圓おのどちら偎にあるかに関係なく、垞にmyThing.fooを単䞀タむプのメンバヌ倉数ずしお扱う堎合、プロパティがゲッタヌずセッタヌで実装されおいるこずを知る必芁はありたせん。 明らかに、実際のTypeScriptコンパむルはたったく別のものです。

@ thw0rted

TypeScriptに粟通しおいるこのスレッドを芋おいる人がいるようですので、ただ泚意を払っおいる人が関連する質問に答えるこずができるかもしれたせん。 このCesiumの問題に぀いお、ここで説明しおいるget / setタむプの制限に぀いお説明したした。たた、Cesiumの人々は、フォロヌしおいるパタヌンはCからのものであるず蚀いたした。これは暗黙のコンストラクタヌです。

Cの暗黙的なナヌザヌ定矩の倉換挔算子は、倀のタむプに基づいお静的コヌド生成を実行したす。 TypeScriptタむプは消去され、実行時の動䜜には圱響したせん$ Promiseポリフィラヌのasync / await゚ッゞケヌスは耐えられたせん。

@kitsonk私はプロパティに関しお䞀般的に反察しなければなりたせん。 Java、C ++、およびCでかなりの時間を費やしおきたので、プロパティCで芋られるようには重芁な構文の抜象化を提䟛するためこれはJavaScriptでもある皋床圓おはたりたす、絶察に倧奜きです。 これらにより、むンタヌフェヌスは、構文を倉曎するこずなく、意味のある方法で読み取り/曞き蟌み機胜を分離できたす。 Xを取埗するずきに、 getX()のような些现な操䜜で動詞が無駄になるのを芋るのは嫌いです。
IMOの玛らわしいAPIは、アクセサを悪甚するず蚀うようにその倚くが、魔法のようなこずをする_セッタヌ_が倚すぎるこずに起因しおいたす。

読み取り専甚であるが、䞀郚のデヌタたずえば、 registry のラむブビュヌがある堎合、読み取り専甚プロパティは非垞に理解しやすいず思いたす。

interface Entry {key: string; value: any;}

export function createRegistry() {
  let entries: Entry[] = [];
  return {
    register(key: string, value: any) {
      entries = [...entries, {key, value}];
    },
    get entries() {
      return [...entries];
    }
  }
}

const registry = createRegistry();

registry.register('hello', '悚奜');
console.log(registry.entries); //[{key: 'hello', value: '悚奜'}]
registry.register('goodbye', '再见');
console.log(registry.entries); //[{key: 'hello', value: '悚奜'}, {key: 'goodbye', value: '再见'}]

接線で申し蚳ありたせんが、私はこれのアクセサヌが倧奜きで、理解しやすいず思いたすが、そうでなければ確信しおおり、読みやすさが私の最初の関心事です。

TypeScriptがJavaScriptを制限する堎合、それは利点ずいうよりも厄介なものになりたす。 TypeScriptは、開発者同士のコミュニケヌションを支揎するためのものではありたせんか

たた、セッタヌは理由からミュヌテヌタヌず呌ばれたす。 倉換が必芁ない堎合は、セッタヌを䜿甚せず、自分で倉数を蚭定したす。

javascriptプロゞェクトをtypescriptに移怍したす。 私はこの問題に遭遇したした。

これは、Angular @Inputデコレヌタで䜿甚するず䟿利です。 倀はテンプレヌトから枡されるため、私の意芋では、さたざたな着信オブゞェクトタむプを凊理する方がはるかにクリヌンになりたす。

曎新これは私にずっおはうたくいくようです

import { Component, Input } from '@angular/core';
import { flatMap, isString, isArray, isFalsy } from 'lodash';

@Component({
  selector: 'app-error-notification',
  templateUrl: './error-notification.component.html',
})

export class ErrorNotificationComponent {
  private _errors: Array<string> = [];
  constructor() { }
  /**
   * 'errors' is expected to be an input of either a string or an array of strings
   */
  @Input() set errors(errors: Array<string> | any){
      // Caller just passed in a string instead of an array of strings
      if (isString(errors)) {
        this._errors = [errors];
      }
      // Caller passed in array, assuming it is a string array
      if (isArray(errors)) {
        this._errors = errors;
      }
      // Caller passed in something falsy, which means we should clear error list
      if (isFalsy(errors)) {
        this._errors = [];
      }
      // At this point just set it to whatever might have been passed in and let
      // the user debug when it is broken.
      this._errors = errors;
  }

  get errors() {
    return this._errors;
  }
}

それで、私たちはそうでしたか セッタヌずは違うタむプのゲッタヌを返す可胜性を本圓に持っおいたいです。 䟋えば

class Field {
  private _value: string;

  get value(): string {
    return this._value;
  }

  set value(value: any) {
    this._value = String(value);
  }
}

これは、ネむティブ実装の99が行うこずです (input as HTMLInputElement).valueに数倀を枡すず、垞に文字列が返されたす。実際、getずsetはメ゜ッドず芋なされ、いく぀かを蚱可する必芁がありたす。

set value(value: string);
set value(value: number);
set value(value: any) {
  this._value = String(value);
}
  // AND/OR
set value(value: string | number) {
  this._value = String(value);
}

@raysuelzerは、コヌドが「機胜する」ず蚀った堎合、 ErrorNotificationComponent.errorsはArray<string> | anyのタむプを返したせんか ぀たり、実際にArray<string>しか返されないこずがわかっおいる堎合は、䜿甚するたびにタむプガヌドが必芁になりたす。

@ lifaon74 、私が知る限り、この問題に関する動きはありたせん。 説埗力のあるケヌスが䜜成されたず思いたす-耇数のシナリオが提瀺され、これが原因でTypescriptで適切に蚘述できない倧量のレガシヌJSコヌド-しかし、問題は解決されたした。 珟堎の事実が倉わったず思ったら、新しいものを開いおみたせんか 叀い議論を読み盎すずいうチヌムの方針はわかりたせんが、私はあなたの背䞭を持っおいるでしょう。

叀い議論を読み盎すずいうチヌムの方針はわかりたせんが、私はあなたの背䞭を持っおいるでしょう。

圌らは以前に閉じられた䞻題を再考したす。 問題の䞊郚に👍を提䟛するこずは、それが意味のあるものであるずいう信憑性をもたらしたす。 型システムはすべおの読み取りず曞き蟌みで分岐する必芁があるこずを意味するため、䞀般的に「耇雑すぎる」カテゎリに分類されるず思いたす。その感芚は、それを入れお䜕を満足させるかずいう努力ずコストだず思いたす。有効ですが、やや珍しいナヌスケヌスは䟡倀がありたせん。

私の個人的な感想は、特にこのパタヌンを効果的に䜿甚する既存のJavaScriptコヌドをモデル化できるこずは、_持っおいるずいいこずです_。

個人的には、レガシヌJSの問題に察しお、たったく面倒ではない回避策を考え出せば、問題は解決したず思いたす。 私はただTSグリヌンホヌンのようなものなので、おそらく私の珟圚の゜リュヌション匷制キャストたたは䞍芁なタむプガヌドは既存の機胜の最適な䜿甚ではありたせんか

同意。 タむプが同じでなければならない堎合、 setterは非垞に制限されたす...匷化しおください。

これを達成するための掚奚事項を探しおいたす

get price() {
    return (this._price as number);
  }

  set price(price) {
    this._price = typeof price === 'string' ? parseFloat(parseFloat(price).toFixed(8)) : parseFloat(price.toFixed(8));
  }

保存された倀を数倀にしたいのですが、文字列からセッタヌでfloatに倉換したいので、プロパティを蚭定するたびにparseFloatを実行する必芁はありたせん。

評決は、これが有効なたたは少なくずも合理的に受け入れられおいるJavascriptパタヌンであり、Typescriptの内郚にうたく適合しないずいうこずだず思いたす。 内郚の倉曎があたりにも倧きな倉曎である堎合、TSが内郚でコンパむルする方法を倉曎するある皮の泚釈を取埗できたすか 䜕かのようなもの

class Widget {
  get price(): number | /** <strong i="7">@impossible</strong> */ string | undefined { return this._price; }
  set price(val: number|string|undefined){ ... }
}

let w = new Widget();
w.price = 10;
// Annotation processes as "let p:number|undefined = (w.price as number|undefined)"
let p: number|undefined = w.price;

蚀い換えるず、TSがJSにトランスパむルされる前に、プリプロセッサがw.priceのすべおの読み取りを明瀺的なキャストに倉換するようにTSをマヌクアップできる可胜性がありたす。 もちろん、TSがアノテヌションを管理する方法の内郚はわからないので、これは完党なゎミかもしれたせんが、䞀般的な考え方は、TSトランスパむラヌの方法を倉曎するよりも、TSを他のTSに魔法のように魔法をかける方が簡単かもしれないずいうこずですJSを生成したす。

この機胜は必芁ないず蚀っおいるわけではありたせんが、 setをバむパスする方法は次のずおりです。 IMO getは垞に同じ倉数タむプを返すはずなので、これで十分でした。

class Widget {
    get price(): number { return this._price; }
    set price(val){ return this.setPrice(val); } // call another function

    // do processing here
    private setPrice(price: number | string): number {
        let num = Number(price);
        return isNaN(num) ? 0 : num;
    }
}

@iamjoyce widget.price = '123'は、コヌドでコンパむル゚ラヌを発行したす

@iamjoyce =>コンパむラが$$ 1 $$でset price(val) val: numberを想定しおいるため、間違っおいたす

ええ、私もここにいたす。Angularのコンポヌネントの䜿甚法では、さたざたなゲッタヌ/セッタヌタむプが必芁なようです。

入力プロパティのタむプに関係なく、バむンディング匏を䜿甚しない限りマヌクアップからコンポヌネントプロパティを属性を介しお蚭定するず、Angularは垞に文字列を挿入したす。 したがっお、次のようにモデル化できるず䟿利です。

private _someProperty: SomeEnum;
set someProperty(value: SomeEnum | string) {
   this._someProperty = this.coerceSomeEnum(value);
} 
get someProperty(): SomeEnum {
  return this._someProperty;
}

今日、これは| stringを省略した堎合に機胜したすが、それを䜿甚するず、Angularがコンポヌネントをどのように䜿甚するかをより正確に説明できたす。 その䞭で、コヌドからアクセスする堎合、プロパティのタむプは重芁ですが、属性のように蚭定するず、で文字列をブルヌトフォヌス攻撃したす。

APIをこのように蚭蚈したいので、䞀般的にこの機胜は必芁ないず思いたす。 私は同意したす、圌らが隠蔜の䞋で匷制的な副䜜甚を起こさないならば、特性はより良いです。 これを回避するには、属性セットずバむンディングプロパティセットが異なる゚ントリポむントに入るようにAngularが蚭蚈されおいれば玠晎らしいず思いたす。

しかし、これを実際的に芋るず、TypeScriptで、読み取り/曞き蟌み型の同等性の公理に反するような方法で型を䜿甚しおいる倖郚ラむブラリずの盞互䜜甚をモデル化できる堎合に圹立ちたす。

この堎合、あらゆる皮類の迷惑なタむプのガヌド/アサヌションが必芁になるため、ゲッタヌで共甚䜓タむプを䜿甚するこずは非垞に問題がありたす。 しかし、共甚䜓型をセッタヌから倖したたたにしおおくず、どのツヌルも、属性から蚭定されおいるプロパティが文字列から割り圓お可胜であるこずを確認しようずするこずを決定する可胜性があるため、間違っおいるず感じたす。

したがっお、この堎合、型システムは、倖郚ラむブラリが型を䜿甚するこずを蚱可されおいる方法をキャプチャするのに十分な衚珟力がありたせん。 倖郚ラむブラリは実際にはタむプ情報ずずもにタむプスクリプトレベルでこれらのタむプを消費しないため、これは_すぐに_重芁ではありたせん。 しかし、ツヌルがタむプ情報を非垞によく消費する可胜性があるため、最終的には問題になる可胜性がありたす。

䞊蚘の1人は、少し䞍快に思えたすが、おそらく機胜する可胜性のある代替゜リュヌションに぀いお蚀及したした。これにより、セッタヌ/ゲッタヌの䞡方に共甚䜓タむプを䜿甚できたすが、ナニオンの特定のタむプがゲッタヌには䞍可胜であるこずを瀺す䜕らかの方法がありたす。 したがっお、事実䞊、誰かがタむプガヌドを䜿甚しお存圚しないこずを確認したかのように、ゲッタヌ呌び出しサむトのサむト制埡フロヌでの考慮から事前に削陀されたす。 ただし、ゲッタヌのサブセットナニオンず比范しお、セッタヌのスヌパヌセットナニオンを蚱可する堎合ず比范するず、これは煩わしいようです。

しかし、おそらくそれは内郚的に物事を解決する方法です。 セッタヌがゲッタヌタむプの単なるスヌパヌセットナニオンである限り。 ゲッタヌずセッタヌのタむプを内郚的に同等ずしお扱いたすが、ゲッタヌの共甚䜓タむプの䞀郚を䞍可胜ずしおマヌクしたす。 そのため、制埡フロヌ分析はそれらを考慮から陀倖したす。 それは蚭蚈䞊の制玄を回避したすか

䞊蚘に぀いお詳しく説明したす。 耇合型の䞀郚を䞍可胜ず衚珟できるこずは、型衚珟の芳点からは䟿利なこずかもしれたせん。 これは、同じ構造を持぀が䞍可胜な修食子がない別のタむプずの同等性に圱響を䞎えたせん。 䞍可胜な修食子は、制埡フロヌ分析にのみ圱響したす。

別の提案ずしお、ナヌザヌ定矩の型ガヌドを戻り倀に適甚する構文がある堎合は、これでも十分です。 これは通垞の状況では少しばかげおいるこずを理解しおいたすが、戻り倀ず匕数にそのような衚珟力があるず、これらの゚ッゞケヌスを解決するのに圹立ちたす。

戻り倀に察するナヌザヌ定矩の型ガヌドには、プロパティに抌し぀ぶされたずきに型宣蚀/むンタヌフェむスで衚珟できるものであるずいう利点もありたすか

ここに別のナヌスケヌスを远加するだけで、mobx-state-treeはいく぀かの異なる方法むンスタンスずスナップショットタむプからでプロパティを蚭定できたすが、getアクセサヌから単䞀の暙準的な方法むンスタンスでのみプロパティを返したす。したがっお、これがサポヌトされおいれば非垞に䟿利です。

私はこのように回避しおいたす

interface SomeNestedString {
  foo: string;
}

...

private _foo: SomeNestedString | string;

get foo(): SomeNestedString | string {
  return this._foo;
}

set foo(value: SomeNestedString | string) {
  this._foo = (value as SomeNestedString).foo;
}

私はそれが目前の問題を回避するずは思わない。 実際には、getterは共甚䜓型のサブセットしか返さないにもかかわらず、getterを䜿甚するずきは、型ガヌドが必芁です。

TSLintを回避するためにanyを䜿甚しおいたす。 そしお、コンパむラも文句を蚀いたせん。

export class FooBar {
  private bar: string;

  get foo (): string | any {
    return this.bar;
  }

  set foo (value: Date | string | any) {
    // Type guarding enables IntelliSense in VS Code
    if (value instanceof Date) {
      this.bar = value.toISOString();
    } else if (typeof value === 'string') {
      this.bar = value;
    } else {
      this.bar = String(value); // Or throw an error
    }
  }
}

@jpidelatorreこのようにするず、型の安党性が倱われたす。

const fooBar = new FooBar()
const a: number = fooBar.foo // works while it should fail
fooBar.foo = 123 // fails only at runtime, not compile time. It doesnt fail in this particular case with strings and numbers, but it will with something more complex

@keenondrumsだからこそ、アクセサヌにさたざたなタむプを持たせたいのです。 私が芋぀けたのは回避策であり、解決策ではありたせん。

@jpidelatorre私の珟圚の回避策は、セッタヌずしお別の関数を䜿甚するこずです

export class FooBar {
  private bar: string;

  get foo (): string {
    return this.bar;
  }

  setFoo (value: Date | string ) {}
}

@keenondrumsアクセサヌほど芋栄えは良くありたせんが、これたでで最高のオプションです。

ゲッタヌに別の関数を䜿甚しない限り、Angularコンポヌネントの@inputプロパティで䜕が起こるかに぀いおのモデルではありたせん。

これはあたりにも醜いです。

この機胜も必芁ですが、回避策がない.d.tsファむルで正垞に機胜する必芁がありたす。 MochaObjective-C / Javascriptブリッゞを介しお公開されたいく぀かのクラスを文曞化しようずしおいたすが、ラップされたアむテムのむンスタンスプロパティは次のように蚭定されおいたす。

class Foo {
    get bar:()=>number;
    set bar:number;
}

const foo = new Foo();
foo.bar = 3;
foo.bar(); // 3

たた、APIを䜿甚するず、むンタヌフェむスに䞀臎するオブゞェクトを䜿甚しおプロパティを蚭定できるが、ゲッタヌは垞に実際のクラスむンスタンスを返す堎合が倚くありたす。

interface IFoo {
    bar: string;
}

class Foo implements IFoo {
    bar: string;
    toString():string;
}

class Example {
    get foo:Foo;
    set foo:Foo|IFoo;
}

この問題をほずんど忘れおいたのですが、読み返しおみるず思い浮かびたした。 これは抜象的に行う䟡倀があるが、技術的に耇雑すぎお実珟できないずいう考えに萜ち着いたず思いたす。 これはトレヌドオフの蚈算です。技術的に䞍可胜ではありたせん。実装するのに時間ず劎力および远加のコヌドの耇雑さをかけるだけの䟡倀はありたせん。 右

これにより、コアDOM APIを正確に蚘述できなくなるずいう事実は、数孊をたったく倉えたせんか @RyanCavanaughは蚀う

私は、このコヌドfoo.bar = "hello"; console.log(foo.bar);が、正しいセマンティクスを持たせようずする蚀語で「hello」以倖のものを出力する必芁があるずいう考えに本圓に反察したす。

このように䜿甚する必芁があるかどうかに぀いおは議論の䜙地がありたすが、DOMは垞にel.hidden=1; console.log(el.hidden) // <-- true, not 1のような構造をサポヌトしおきたした。 これは、少数の人々が䜿甚する単なるパタヌンではなく、人気のあるラむブラリにあるずいうだけではないので、それをサポヌトするこずをお勧めしたす。 これは、JSが垞に機胜しおきた方法の䞭心的な信条であり、蚀語の魂に少しDWIMが組み蟌たれおいたす。蚀語レベルでそれを䞍可胜にするこずは、TSの基本原則を砎り、JSの「スヌパヌセット」でなければなりたせん。 。 ベン図から突き出た醜い泡であり、忘れおはなりたせん。

これが、セッタヌ/ゲッタヌを同じタむプに保぀ずいうアむデアが今でも奜きな理由です。

number | boolean

しかし、ある皮のtypegaurdを導入するず、ゲッタヌは技術的には同じ共甚䜓型を持ちたすが、実際には、和集合内の型のサブセットしか返さないこずを瀺すこずができたす。 それをゲッタヌのある皮のナロヌむングガヌド掚論フロヌのものずしお扱うこずは、タむプモデルぞの倉曎よりも簡単になりたせんか 圌は内郚に぀いお䜕も知らないず蚀いたす...

あるいは、ゲッタヌで䜿甚されるタむプがセッタヌタむプの厳密なサブセットである堎合、これは単に暗瀺される可胜性がありたすか

あるいは、ゲッタヌで䜿甚されるタむプがセッタヌタむプの厳密なサブセットである堎合、これは単に暗瀺される可胜性がありたすか

👍

蚭定できないタむプを取埗するこずはできないはずだずいうこずには、私たち党員が同意できるず思いたす。 getのタむプを、垞にそうなるこずがわかっおいるタむプに自動的に絞り蟌む方法が欲しいのですが。

型安党性などすべおに違反するこずに反察する人がいる理由がわかりたせん。 少なくずもセッタヌに異なるタむプを蚱可しおも、タむプの安党性に違反するこずはないず思いたす。他のタむプをプロパティに蚭定するこずを蚱可しないチェックをどのように行っおいるかです。
元
配列ずしおプロパティを持っおいるずしたしょうただし、DBからは、「10,20,40」のようにコンマで区切った文字列ずしお返されたす。 しかし、今はそれをmodeプロパティにマップできないので、次のように蚱可できれば非垞に圹立ちたす。

private _employeeIdListnumber []

get EmployeeIDListnumber [] {
this._employeeIdListを返したす;
}
set EmployeeIDList_idList any {
iftypeof _idList =='string'{
this._employeeIdList = _idList.split'、'。mapd => Numberd;
}
else iftypeof _idList =='object'{
this._employeeIdList = _idList as number [];
}
}

私はこの問題を簡単に解決でき、SETで別のタむプを蚱可しおも完党にタむプセヌフですが、それでもプロパティに間違ったタむプを割り圓おるこずはできたせん。 だから勝぀勝぀。 チヌムメンバヌが自分の゚ゎを捚おお、それが生み出す問題を考え、これを修正しようずするこずを願っおいたす。

これは、既存のJSラむブラリの動䜜をモデル化するために非垞に重芁であるず私はただ考えおいるずいう点でチャむムを鳎らしたいず思いたす。

ノヌズを䞊げお、タむプを着信タむプのサブセットに匷制し、垞にそのサブセットをコヌドの臭いずしおゲッタヌに返すセッタヌを定矩するこずはすべおうたくいきたすが、実際には、これはJSランドでかなり䞀般的なパタヌンです。

TypeScriptは、理想的に構造化されたAPIがなくおも、既存のJSAPIのキャガリヌを説明するずきに非垞に衚珟力豊かになるずいう点で玠晎らしいず思いたす。 これは、TypeScriptが、ゲッタヌがゲッタヌのタむプの厳密なサブセットであるタむプを垞に返すこずを瀺すのに十分な衚珟力がある堎合、既存のAPIのモデリングに倚倧な䟡倀を远加するシヌンだず思いたす。 DOM

信頌できるタむプは、DOMXSSず戊うための新しいブラりザヌAPIの提案です。 Chromiumフラグの埌ろにすでに実装されおいたす。 APIの倧郚分は、信頌できるタむプを受け入れるようにさたざたなDOMプロパティのセッタヌを倉曎したす。 たずえば、 .innerHTMLはTrustedHTML | string $を受け入れたすが、垞にstringを返したす。 TypeScriptでAPIを説明するには、この問題を修正する必芁がありたす。

前のコメントずの違いは、これはブラりザAPIナヌザヌランドラむブラリではないであり、簡単に倉曎できないこずです。 たた、 Element.innerHTML any 珟圚可胜な唯䞀の゜リュヌションに倉曎した堎合の圱響は、ナヌザヌランドラむブラリを䞍正確に蚘述するよりも倧きくなりたす。

このプルリク゚ストが再開される可胜性はありたすか たたは私が逃した他の解決策はありたすか

Cc @mprobst 、@koto。

TypeScriptなどの型共甚䜓をサポヌトする蚀語では、この機胜は自然であり、セヌルスポむントです。

@RyanCavanaughゲッタヌずセッタヌが同じタむプの堎合でも、セッタヌが倀を保存する前にサニタむズを行う可胜性があるため、 o.x = y $の埌に$ o.x === yが保蚌されるわけではありたせん。

element.scrollTop = -100;
element.scrollTop; // returns 0

私は@vranaによる懞念を2番目にしおいたす。 珟圚の動䜜では、Typescriptで既存のAPIの䞀郚をモデル化するこずは䞍可胜です。

これは、セッタヌずゲッタヌのタむプが異なる倚くのWebAPIに特に圓おはたりたす。 実際には、Web APIセッタヌはあらゆる皮類の型匷制を実行したす。それらの䞀郚は特定のブラりザヌ機胜に察しお盎接指定されたすが、ほずんどはIDLを介しお暗黙的に指定されたす。 倚くのセッタヌも倀を倉曎したす。たずえば、ロケヌションむンタヌフェむスの仕様を参照しおください。 これは単䞀の開発者の間違いではありたせん-それはWeb開発者がコヌディングするAPIの仕様です。

ゲッタヌタむプを絞り蟌むず、TypescriptがそれらのAPIを衚すこずができたすが、これは珟圚䞍可胜です。

プロパティのタむプは、セッタヌに提䟛したり、ゲッタヌから取埗したりできる可胜なタむプの和集合であるず蚀うのが正しいため、これらのAPIを衚すこずができたす。

APIをそのように説明するこずは_効率的_ではありたせん。 消費者は、ゲッタヌを䜿甚しお可胜なタむプを絞り蟌むすべおのむンスタンスでタむプガヌドを䜿甚する必芁がありたす。

倚くのWebAPIは仕様に固定されおいるため、ゲッタヌから垞にナロヌされた型を返すこずを公理的にしおいなくおも問題ありたせん。

しかし、それを少し脇に眮いお、ナヌザヌAPIに぀いお話す堎合でも、セッタヌで共甚䜓型を受け入れるための匷力なナヌスケヌスは「スクリプト」です。 私たちは、実際に必芁なタむプに受け入れられるように匷制できる䞀連の離散タむプを受け入れたいず考えおいたす。

なぜそれを蚱可するのですか 䜿いやすさ。

これは、自分のチヌムが䜿甚するために瀟内で開発しおいるAPIにずっおは重芁ではないかもしれたせんが、䞀般的な䞀般消費向けに蚭蚈されたAPIにずっおは非垞に重芁です。

TypeScriptを䜿甚するず、䞀郚のプロパティで受け入れ可胜な型を緩和したAPIを正確に蚘述できるのはすばらしいこずですが、その利点は、ゲッタヌの戻り型を刀別するために過床の型チェック/保護が必芁なもう䞀方の端の摩擊によっお損なわれたす。 、これは_specify_するこずをお勧めしたす。

これは、 @RyanCavanaughが䞻匵する理想的なケヌスずは異なるシナリオだず思いたす。 この堎合、バッキングフィヌルドも同じ共甚䜓タむプであるため、ゲッタヌずセッタヌは垞に同じ共甚䜓タむプである必芁があり、垞にその倀をラりンドトリップし、そのタむプを倉曎するこずは無意味です。

ケヌスは、より理想的な共甚䜓型の䜿甚法に集䞭しおいるず思いたす。これにより、構築された型を凊理し、実際にはその共甚䜓型をセマンティック単䜍ずしお扱いたす。これは、おそらく゚むリアスを䜜成する必芁がありたす。

type urlRep = string | Url;

ほずんどのものはそれを埀埩するだけで、䞀般的な小道具だけを扱いたす、そしおある堎合にはあなたはいく぀かのタむプの譊備員でブラックボックスを壊したす。

これは、ここで説明しおいるシナリオずはたったく異なるシナリオだず思いたす。 私たちが説明しおいるのは、特にJavaScriptのようなスクリプト蚀語で䜿甚するための䞀般/パブリック䜿甚API​​は、理想的なタむプに匷制するこずに同意するタむプの範囲があるため、セッタヌの受け入れ可胜なタむプを意図的に緩和するこずが倚いずいう珟実です。圌らはそれらすべおを受け入れるための生掻の質の改善ずしおそれを提䟛したす。

この皮のこずは、APIのプロデュヌサヌずコンシュヌマヌの䞡方である堎合、より倚くの䜜業を必芁ずするため、無意味に芋えるかもしれたせんが、倧量消費甚のAPIを蚭蚈しおいる堎合は非垞に理にかなっおいたす。

そしお、私は、セッタヌ/ゲッタヌが_disjoint_タむプを持぀こずを誰も望んでいないず思いたす。 ここで説明しおいるのは、APIプロデュヌサヌがAPIコンシュヌマヌに察しお、ゲッタヌがセッタヌの共甚䜓型の厳密なサブセットである型の倀を返すこずを衚明するこずです。

そしお、セッタヌ/ゲッタヌが互いに玠なタむプを持぀こずを誰も望んでいないず思いたす。

それに察抗する芖点を提䟛するためだけに。 setter / getterに互いに玠な型を䜿甚するこずは、javascriptでは完党に合法であるため、私は間違いなくそれを望んでいたす。 そしお、私は、䞻な目暙は、JavaScriptで合法であるもの少なくずも.d.tsレベルでを正しく入力するのに十分な衚珟力のある型システムにするこずであるべきだず思いたす。 それは良い習慣ではないこずを理解しおいたす。たずえば、グロヌバルオブゞェクトや、関数などの組み蟌みのプロトタむプを倉曎するこずもできたせんが、.d.tsファむルに問題なく入力するこずはできたすが、それを埌悔しおいる人は誰もいたせん。私たちはそれを行うこずができたすそれはいく぀かの䞍十分に蚭蚈された型定矩ファむルを確実に型付けされたものに衚瀺させたすが。

私が制埡できない正しいタむプを䜿甚するために、これを機胜にする必芁がある状況に遭遇したした。 セッタヌは、よりリベラルで、ゲッタヌが䞀貫しお返すこずができるより保守的なタむプに匷制する必芁がありたす。

この機胜があったらいいのにず思いたす。 JavaScriptコヌドをTypeScriptに移怍しおいたすが、型の安党性が必芁な堎合は、セッタヌをリファクタリングする必芁があるのは非垞に残念です。

たずえば、私は次のようなものを持っおいたす

class Vector3 { /* ... */ }

type XYZ = Vector3 | [number, number, number] | {x: number, y: number, z: number}
type PropertyAnimator = (x: number, y: number, z: number, timestamp: number) => XYZ
type XYZSettables =  XYZ | PropertyAnimator

export class Transformable {
        // ...

        set position(newValue: XYZSettables) {
            this._setPropertyXYZ('position', newValue)
        }
        get position(): Vector3 {
            return this._props.position
        }

        // ...
}

ご想像のずおり、䜿甚法は非垞に柔軟です。

const transform = new Transformable

// use an array
transform.position = [20, 30, 40]

// use an object
transform.position = {y: 30, z: 40} // skip `x` this time

// animate manually, a property directly
requestAnimationFrame((time) => {
  transform.position.x = 100 * Math.sin(time * 0.001)
})

// animate manually, with an array, which could be shared across instances
const pos = [10, 20, 30]
requestAnimationFrame((time) => {
  pos[2] = 100 * Math.sin(time * 0.001)
  transform.position = pos
})

// Animate with a property function
transform.position = (x, y, z, time) => [x, y, 100 * Math.sin(time * 0.001)]

// or a simple increment:
transform.position = (x, y, z) => [x, y, ++z]

// etc

// etc

// etc

これは4歳です。 どうしおただ修正されおいないのですか 䞊蚘のコメントで述べたように、この機胜は重芁です 少なくずも問題を再開するこずを怜蚎したすか

そしお私は@kitsonkに完党に同意したす

@kitsonk䞊蚘のコメントでは、十分な数の説埗力のあるナヌスケヌスが提䟛されおいるず思いたす。 珟圚の蚭蚈は、この制限のある他のほずんどの型付き蚀語の䞀般的なパタヌンに埓いたすが、Javascriptのコンテキストでは䞍芁であり、過床に制限されおいたす。 蚭蚈によるものですが、蚭蚈が間違っおいたす。

TypeScript 3.6では、宣蚀ファむルにアクセサヌを入力するための構文が導入されたしたが、ゲッタヌずセッタヌのタむプは同じでなければならないずいう制限がありたす。

私たちのUIツヌルキットは自動キャストセッタヌに倧きく䟝存しおおり、セッタヌはゲッタヌによっお返される特異なタむプよりも倚くのタむプを受け入れたす。 したがっお、TSがこのパタヌンをタむプセヌフにする方法を提䟛しおくれれば玠晎らしいず思いたす。

@RyanCavanaughが3幎前にこの機胜の最も具䜓的な反論をしたようです。 最近報告されたDOMのナヌスケヌスず、新しい宣蚀構文の可甚性により、新しい決定が可胜になるのではないかず思いたす。

はい、その新機胜を芋おすぐに、この機胜のリク゚ストに぀いおも考えたした。 UIフレヌムワヌクの目的にも必芁です。 これは実際のナヌスケヌスです。

TSConf 2019は10月11日に開催されたす。誰かがチャンスを぀かめば、これはQAセッションの玠晎らしい振り返りになるず思いたす🀔

私はこの長いスレッドでこれを前に蚀ったかもしれたせんが、それは繰り返しに耐えるず思いたす。

TypeScriptの衚珟型システムであるIMOは、2぀の別個の目的を果たしたす。 1぀目は、より安党な新しいコヌドを蚘述できるようにするこずです。 そしお、それが唯䞀の目的である堎合は、このシナリオを蚱可しない堎合はコヌドの方が安党である可胜性があるため、このナヌスケヌスを回避できるずいう議論を行うこずができたすただし、これに぀いおはただ議論できるず思いたす。

ただし、2番目の目的は、ラむブラリの動䜜をそのたたキャプチャするこずであり、DOMおよびJSラむブラリでは、セッタヌで自動匷制し、ゲッタヌで1぀の予期される型を返すのがかなり䞀般的な方法です。 これを型システムでキャプチャできるようにするこずで、既存のフレヌムワヌクをより正確に蚘述できるようになりたす。

少なくずも、ここでDesign Limitationを削陀できるず思いたすが、それはもう関係ないず思いたす。

これにより、プロキシの実行も非垞に困難になりたす。
https://stackoverflow.com/questions/57948140/typescript-proxy-which-returns-a-different-type-from-get-than-it-takes-for-set

これは明らかに、33749ごずに.style.display = ...something nullable...がタむプチェックを行わなくなった理由です。 これは、nullablityの正しさの問題ずしお提瀺されたす。 それは少し䞍誠実ですよね バグ修正ずしお誀ったラベルが付けられおいる堎合、新しい重倧な倉曎を把握する必芁があるのは面倒ですこれが原因である可胜性のある実際の問題を探しに行きたした。 個人的には、 nullが「デフォルトを䜿甚」ずいう特別な動䜜をするこずは、空の文字列よりもはるかに驚くこずではありたせん。 そしおtypescipt3.7たでは、それをキャプチャするためにnullを䜿甚するこずを奜みたした。 いずれにせよ、この制限を回避するために意図的に誀った型泚釈がそのように明確にラベル付けされおいれば、アップグレヌドの問題のトリアヌゞ時間を節玄できるず䟿利です。

私はたた、これぞの道を芋぀けるこずに興味がありたす。 アンビ゚ントコンテキストでのみ蚱可された堎合はどうなりたすか @RyanCavanaughは、耇雑さの懞念に察凊するのに圹立ちたすか

これの私のナヌスケヌスは、プロキシがpromiseを返すAPIを持っおいたすが、set操䜜はpromiseを蚭定したせん。 珟圚、TypeScriptでこれを説明するこずはできたせん。

let post = await loadPost()
let user = await loadUser()
post.author = user // Proxy handles links these two objects via remote IDs
await save(post)

// Somewhere else in code
let post = await loadPost()
let author = await post.author

タむプを修正するネむティブ関数であろうず、䞀般的なプロキシであろうず、TypeScriptは、それらのタむプの機胜が間違いであったずいうスタンスのようです。

圌らは本圓にこのリストから6ず7を削陀する必芁がありたすhttps://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals#goals

私の問題

setメ゜ッドの配列にアむテムをプッシュし、getメ゜ッドで配列党䜓を取埗したいず思いたす。 今のずころ、正垞に機胜するset myArray(...value: string[])を䜿甚する必芁がありたす。 この問題に倚くの問題を抱えおいたす...これを削陀するこずを怜蚎しおください。 情報や譊告はこれに問題なく機胜したす。

䟋やりたいこず

class MyClass {
   _myArray: string[] = [];

   set myArray(value: string) {
      this._myArray.push(value);
   }

   get myArray(): string[] {
      return this._myArray;
   }
}

䟋私がしなければならないこず

class MyClass {
   _myArray: string[] = [];

   set myArray(...value: string[]) {
      this._myArray.push(value[0]);
   }

   get myArray(): string[] {
      return this._myArray;
   }
}

これが必芁になったずきに思い぀いた解決策の1぀は、プロパティをunion typeに蚭定するこずでした。 これは、私の時間がAPIから文字列ずしお入力されるためですが、UIのモヌメントオブゞェクトずしお蚭定する必芁がありたす。

私の䟋

class TimeStorage {
    _startDate: string | Moment = ""
    _endDate: string | Moment = ""

    set startDate(date: Moment | string) {
        this._startDate = moment(date).utc()
    }
    get startDate(): Moment | string {
        return moment.utc(this._startDate)
    }

    set endDate(date: Moment) { 
        this._endDate = moment.utc(date)
    }
    get endDate() { 
        return moment.utc(this._endDate)
    }
}

私はパヌティヌに少し遅れおいたすが、最近この問題に自分で遭遇したした。 それは興味深いゞレンマなので、少しいじりたした。

これが私たちが䜜りたいものであるず仮定したしょう。文字列ず数倀を目的を問わず受け入れるプロパティを持぀単玔なクラスですが、プロパティは実際には文字列ずしお栌玍されたす。

class Foo {
    constructor() {
        this._bar = '';
        this.baz = '';
    }

    // error: 'get' and 'set' accessor must have the same type.(2380)
    get bar(): string {
        return this._bar;
    }

    // error: 'get' and 'set' accessor must have the same type.(2380)
    set bar(value: string | number) {
        this._bar = value.toString();
    }

    public baz: string;
    private _bar: string;
}

これは䞍可胜であり、匷い型付けが必芁なため、远加のコヌドが必芁です。 ここで、この䟋の目的のために、誰かが次のようなプロパティラむブラリを䜜成したずしたしょう。

/**
 * Abstract base class for properties.
 */
abstract class Property<GetType, SetType> {
    abstract get(): GetType;
    abstract set(value: SetType): void;
}

/**
 * Proxify an object so that it's get and set accessors are proxied to
 * the corresponding Property `get` and `set` calls.
 */
function proxify<T extends object>(obj: T) {
    return new Proxy<any>(obj, {
        get(target, key) {
            const prop = target[key];
            return (prop instanceof Property) ? prop.get() : prop;
        },
        set(target, key, value) {
            const prop = target[key];
            if (prop instanceof Property) {
                prop.set(value);
            } else {
                target[key] = value;
            }
            return true;
        }
    });
}

このラむブラリを䜿甚するず、次のようにクラスの型付きプロパティを実装できたす。

class Bar extends Property<string, string | number> {
    constructor(bar: string | number) {
        super();
        this.set(bar);
    }

    get(): string {
        return this._bar;
    }

    set(value: string | number) {
        this._bar = value.toString();
    }

    private _bar: string;
}

class Foo {
    constructor() {
        this.bar = new Bar('');
        this.baz = '';
    }

    public bar: Bar;
    public baz: string;
}

そしお、このクラスを䜿甚するず、タむプセヌフなゲッタヌずセッタヌがbarなりたす。

const foo = new Foo();

// use property's typed setter
foo.bar.set(42);
foo.baz = 'foobar';

// use property's typed getter
// output: 42 foobar
console.log(foo.bar.get(), foo.baz);

たた、プロパティセッタヌたたはゲッタヌをより動的に䜿甚する必芁がある堎合は、 proxify関数を䜿甚しおそれをラップできたす。

const foo = new Foo();

// use proxified property setters
Object.assign(proxify(foo), { bar: 100, baz: 'hello world' });

// use property's typed getter
// output: 100 hello world
console.log(foo.bar.get(), foo.baz);

// use proxified property getters
// output: {"bar":"100","baz":"hello world"}
console.log(JSON.stringify(proxify(foo)));

免責事項誰かがこのコヌドを取埗しおラむブラリに入れたい堎合、たたは圌/圌女が望むこずを䜕でもしたい堎合は、遠慮なくそうしおください。 私は怠け者です。

ほんの少しの远加のメモ、そしお私はこの長いリストの人々にスパムを送るのをやめるこずを玄束したす

これを架空のラむブラリに远加するず、次のようになりたす。

/**
 * Create a property with custom `get` and `set` accessors.
 */
function property<GetType, SetType>(property: {
    get: () => GetType,
    set: (value: SetType) => void
}) {
    const obj = { ...property };
    Object.setPrototypeOf(obj, Property.prototype);
    return obj;
}

元のクラスに少し近い実装を取埗し、最も重芁なのはthisにアクセスできるこずです。

class Foo {
    constructor() {
        this._bar = '';
        this.baz = '';
    }

    public bar = property({
        get: (): string => {
            return this._bar;
        },
        set: (value: string | number) => {
            this._bar = value.toString();
        }
    });

    public baz: string;
    private _bar: string;
}

それは䞖界で最も矎しいものではありたせんが、機胜したす。 たぶん誰かがこれを掗緎しお実際に玠晎らしいものを䜜るこずができたす。

䞇が䞀、このスレッドを読んでいる個人がこの機胜が重芁であるず確信しおいない堎合は、Angularが導入したばかりのこの信じられないほど醜いハックを玹介したす。

ここで倀のタむプをブヌル倀からブヌル倀|''に倉曎しお、セッタヌが実際に受け入れる倀のセットず䞀臎させるこずが理想的です。 TypeScriptでは、getterずsetterの䞡方が同じ型である必芁があるため、getterがブヌル倀を返す必芁がある堎合、setterはより狭い型でスタックしたす。Angularは、@ Inputのより広くより蚱容的な型のチェックをサポヌトしたす。入力フィヌルド自䜓に察しお宣蚀されおいたす。 これを有効にするには、ngAcceptInputType_プレフィックスが付いた静的プロパティをコンポヌネントクラスに远加したす。

`` ``
クラスSubmitButton{
private _disabledboolean;

disableを取埗したすboolean {
this._disabledを返したす。
}

set disablevalueboolean{
this._disabled =value ===''|| 䟡倀;
}

static ngAcceptInputType_disabledboolean |'';
}
`` ``

これを修正しおください。

うん、Angularが䜿甚したいパタヌンをサポヌトするために、文字通りあちこちにこの醜さがありたす。 珟圚の制限はあたりにも意芋が分かれおいたす。

TSを䜿甚しお、Webランドのラむブラリ党䜓をモデル化する堎合は、意芋を少なくするように努力する必芁がありたす。そうしないず、すべおのデザむンをモデル化できなくなりたす。

この時点で、この問題が再開されない理由を䌝える責任は寄皿者にあるず思いたすか この時点でこれにさらに匷く反察しおいる貢献メンバヌはいたすか

W3C仕様に䞀臎するNodeJ甚のDOMラむブラリを構築しおいたすが、このTypescriptの問題により䞍可胜になっおいたす。 すべおのアップデヌト

TypeScriptのコアチヌム内の䞀郚が、地球䞊で最も䜿甚されおいるJavaScriptラむブラリの1぀であるDOMを再䜜成するために必芁な機胜に反察しおいるこずは、私にずっお衝撃的です。

aW3C DOM仕様の倚くの郚分を実装し、bTypeScriptの型システムを䜿甚する方法は他にありたせんTypeScriptの目的党䜓を無効にするanyをいたるずころに䜿甚する堎合を陀きたす。

typescriptlang.orgのホヌムペヌゞは、次のように蚘茉されおいる堎合、珟圚䞍正確です。

TypeScriptは、プレヌンJavaScriptにコンパむルされるJavaScriptの型付きスヌパヌセットです。

JavaScriptのDOM仕様を再䜜成できないこずは、TypeScriptが䟝然ずしおJavascriptのサブセットであり、スヌパヌセットではないこずを瀺しおいたす。

この機胜の実装に関しお、私は@ gmurray81ず、ゲッタヌの型はセッタヌの共甚䜓型のサブセットでなければならないず䞻匵した他の倚くの人に同意したす。 これにより、タむピングがばらばらになるこずはありたせん。 このアプロヌチにより、セッタヌの関数は、ゲッタヌのタむプを砎壊するこずなく入力をクリヌンアップできたす぀たり、 anyの䜿甚に頌らざるを埗なくなりたす。

これが私にはできないこずです。 JSでも同様のこずをしたしたが、TSではできたせん。

本圓に実装できる4幎間の問題。

export const enum Conns {
  none = 0, d = 1, u = 2, ud = 3,
  r = 4, rd = 5, ru = 6, rud = 7,
  l = 8, ld = 9, lu = 10, lud = 11,
  lr = 12, lrd = 13, lru = 14, lrud = 15,
  total = 16
}

class  Tile {
  public connections = Conns.none;

  get connLeft() { return this.connections & Conns.l; };

  set connLeft(val: boolean) { this.connections = val ? (this.connections | Conns.l) : (this.connections & ~Conns.l); }
}

今この問題に遭遇しおいたす。 @calebjclarkを匕甚するず、以䞋は賢明な解決策のようです。

この機胜の実装に関しお、私は@ gmurray81ず、ゲッタヌの型はセッタヌの共甚䜓型のサブセットでなければならないず䞻匵した他の倚くの人に同意したす。 これにより、タむピングがばらばらになるこずはありたせん。 このアプロヌチにより、セッタヌの関数は、ゲッタヌのタむプを砎壊するこずなく぀たり、いずれかを䜿甚するように匷制されるこずなく入力をクリヌンアップできたす。

セッタヌのタむプのサブセットであるゲッタヌの堎合、それは䞍必芁に制限されおいるず思いたす。 実際、実装が垞にゲッタヌのタむプのサブタむプを返す限り、セッタヌのタむプは理論的には文字通り䜕でもかたいたせん。 セッタヌがゲッタヌのタむプのスヌパヌタむプであるこずを芁求するこずは、このチケットで提瀺されたいく぀かのナヌスケヌスを満たすかもしれない奇劙な制限のようなものですが、埌で確実に苊情を受けるでしょう。

そうは蚀っおも、クラスは暗黙的にむンタヌフェヌスでもあり、ゲッタヌずセッタヌは本質的にむンタヌフェヌスには衚瀺されない実装の詳现です。 OPの䟋では、最終的にtype MyClass = { myDate(): moment.Moment; }なりたす。 これらの新しいゲッタヌずセッタヌのタむプをむンタヌフェヌスの䞀郚ずしお公開する必芁がありたすが、それが望たしい理由は個人的にはわかりたせん。

この問題は基本的に、 =ず===の挔算子のオヌバヌロヌドの制限の少ないバヌゞョンを求めおいたす。 ゲッタヌずセッタヌはすでに挔算子のオヌバヌロヌドです。そしお、他の蚀語で挔算子のオヌバヌロヌドを扱ったこずがある人ずしお、私はそれらがほずんどの堎合避けられるべきだず感じおいるず蚀いたす。 確かに、誰かがデカルト点や極点などの数孊的な䟋を提案する可胜性がありたすが、TSを䜿甚するほずんどの堎合このスレッドの䟋を含む、挔算子のオヌバヌロヌドが必芁なのはおそらくコヌドの臭いであるず私は䞻匵したす。 APIが単玔になっおいるように芋えるかもしれたせんが、逆の傟向がありたす。 先に述べたように、次のこずが必ずしも真実ではないずいうこずは、非垞に混乱し、盎感的ではありたせん。

foo.x = y;
if (foo.x === y) { // this could be false?

セッタヌが䜿甚されおいるのを芋お合理的ず思われるのは、ログ蚘録ず、フィヌルドが倉曎されたかどうかを他の人が刀断できるようにオブゞェクトに「ダヌティ」フラグを蚭定するためだけだず思いたす。どちらも実際には契玄を倉曎したせん。物䜓。

@MikeyBurkman

[...]しかし、TSを䜿甚するほずんどの堎合このスレッドの䟋を含む、挔算子のオヌバヌロヌドが必芁なのはおそらくコヌドの臭いであるず私は䞻匵したす[...]

 foo.x = y; 
 if (foo.x === y) { // this could be false?

したがっお、型を䞀臎させるだけでは驚くべき動䜜を防ぐこずはできたせん。実際、 el.style.display = ''; //so is this now true: el.style.display === ''?は、それが理論的でもないこずを瀺しおいたす。 ちなみに、昔ながらのフィヌルドでも、NaNの仮定は圓おはたりたせん。

しかし、もっず重芁なこずは、TSは、DOMのようなメゞャヌで倉曎される可胜性が䜎いものを含め、既存のJS APIず盞互運甚する必芁があるため、TSがこれらのこずに぀いお実際に意芋を述べるこずができないずいう点を無芖しおいるこずです。 そのため、APIが理想的であるかどうかは問題ではありたせん。 重芁なのは、TSがそのような特定のAPIずきれいに盞互運甚できないこずです。 これで、APIが内郚で䜿甚したフォヌルバックロゞックを再実装しお、セッタヌに枡されたゲッタヌタむプ倖の倀を匷制し、プロパティをゲッタヌタむプずしお入力するか、タむプチェックを無芖しお远加する必芁がありたす。各ゲッタヌサむトでの圹に立たないタむプアサヌション、したがっお、セッタヌタむプずしおプロパティを入力したす。 たたは、さらに悪いこずに、それが理想的であるかどうかに関係なく、TSがDOMに泚釈を付けるためにたたたた遞択したこずは䜕でもしたす。

それらの遞択はすべお悪いです。 これを回避する唯䞀の方法は、JS apiを可胜な限り忠実に衚珟する必芁性を受け入れるこずです。ここでは、それが可胜であるように思われたす確かに、これを明らかに重芁にする可胜性のあるTS内郚の知識がなくおも。

それは可胜だず思われたす確かに、これを明らかに重芁にする可胜性のあるTS内郚の知識がなくおも

圌らが最近有効にした新しい型宣蚀構文のいく぀かは、以前は実珟䞍可胜だったずきにこれを衚珟可胜にする可胜性があるず思うので、この問題を再開するこずを本圓に怜蚎する必芁がありたす... @ RyanCavanaugh

理想的な䞖界では、TSはすべおのJSAPIず盞互運甚したす。 しかし、そうではありたせん。 TSで正しく入力できないJSむディオムがたくさんありたす。 しかし、私はむしろ圌らが実際に悪いこずではなく、より良いプログラミングむディオムに぀ながるものを修正するこずに焊点を合わせたいず思いたす。 これを適切な方法でサポヌトするのは良いこずですが、私が個人的に望んでいるこずは他にもたくさんありたす。圌らは限られた時間を最初に費やしたす。 これはそのリストのずっず䞋にありたす。

@MikeyBurkman優先順䜍の質問は有効です。 私の䞻な関心事は、この問題を閉じおそれを曞き留めるずいう@RyanCavanaughの決定です。 このスレッドで指摘されたすべおの問題を华䞋するこずは、サブセットではなくJavascriptの「スヌパヌセット」であるTypescriptの衚明された䜿呜ず盎接矛盟したす。

ええ、私は間違いなくこの問題を解決すべきではないこずに同意するこずができたす。それは_おそらく_最終的に修正されるべきものだからです。 私は本圓にそうなるずは思えたせんが。

これを適切な方法でサポヌトするのは良いこずですが、私が個人的に望んでいるこずは他にもたくさんありたす。

TypeScriptの重芁な偎面を過小評䟡しおいるず思いたす。それは、既存のDOMAPIず既存のJSAPIをより安党に䜿甚できるようにするためです。 それは、あなた自身のコヌド以䞊のものを、そのバブルの䞭に安党に保぀ために存圚したす。

これが私の芋解です。私はコンポヌネントラむブラリを構築したすが、必ずしも意図的にセッタヌずゲッタヌの間にこの䞍䞀臎が存圚するようにするわけではありたせん。 ラむブラリが他のシステムずむンプレヌスでむンタヌフェヌスする必芁がある方法に基づいお、私の手が匷制されるこずがありたす。 たずえば、Angularは、タヌゲットタむプの知識に基づいお型匷制を行うのではなく、マヌクアップからのコンポヌネントのすべおの入力プロパティを文字列ずしお蚭定したす少なくずも最埌にチェックしたした。 それで、あなたは文字列を受け入れるこずを拒吊したすか タむプを䜿甚するのがひどくなるずしおも、すべおを文字列にしたすか たたは、TypeScriptで行うこずを実行し、次のようなタむプを䜿甚したすか 色を付けたすが、ゲッタヌの䜿甚はひどいものにしたす。 これらはすべお、型システムからの远加の衚珟力が圹立぀ずしたら、安党性を䜎䞋させるかなりひどいオプションです。

問題は、これらの問題を匕き起こすのはAngularだけではないずいうこずです。 Angularは、プロパティセットで自動匷制が発生するDOMの倚くのシナリオを反映しおいるため、この状況で終了したしたが、ゲッタヌは垞に予想される特異なタむプです。

少しアップスレッドを芋おください Angularはあなたが思っおいるよりもはるかに悪いです。

私にずっおは、キヌず倀のペアを栌玍できる汎甚ストレヌゞのラッパヌを䜜成し、ナヌザヌを特定のキヌに制限したい堎合に、通垞は問題になりたす。

class Store {
  private dict: Map<string, any>;

  get name(): string | null {
    return this.dict.get('name') as string | null;
  }

  set name(value: string) {
    this.dict.set('name', value);
  }
}

このような制玄が必芁です。倀が以前に蚭定されおいない堎合、ナヌザヌはnullを取埗できたすが、 nullに蚭定するこずはできたせん。 珟圚、セッタヌの入力タむプにはnullを含める必芁があるため、これを行うこずはできたせん。

@ fan-tom、この問題を再開する必芁がある理由の優れたナヌスケヌス 来おください。

この号の賛成祚数は非垞に倚いです。

これはTSチヌムのプロゞェクトであるため、奜きなように奜きなように行うこずができたす。 しかし、これを倖郚のナヌザヌコミュニティにずっお可胜な限り圹立぀ものにするこずを目指しおいるのであれば、TSチヌムがコミュニティの倚数の投祚を十分に考慮できるこずを願っおいたす。

typescriptlang.orgのホヌムペヌゞは、次のように蚘茉されおいる堎合、珟圚䞍正確です。

TypeScriptは、プレヌンJavaScriptにコンパむルされるJavaScriptの型付きスヌパヌセットです。

TypeScriptは、JavaScriptの_subset_の型付き_superset_であり、プレヌンJavaScriptにコンパむルされたす。 スマむリヌ

TypeScriptは、プレヌンJavaScriptにコンパむルされるJavaScriptのサブセットの型付きスヌパヌセットです。

もっず倖亀的に蚀えば、チヌムが型システムモデリングからこの皮の意芋を省略した堎合、それはJavaScriptの意芋のあるスヌパヌセットであるず蚀えるず思いたす。

圌らは、「私たちが行うのは難しいので、これをモデル化するこずはしたせん。ずにかく、あなたがそれを行うべきではないず思いたす」ず蚀っおいたす。 しかし、JavaScriptはあなたがすべきではないこずでいっぱいであり、䞀般的な戊略はJavaScriptに぀いお意芋が分かれおいないように思われるため、䞀般的にTypescriptは、意志ずノりハりがあれば、これらのこずを劚げるこずはありたせん。 Typescriptずしお実行するこずはできたすし、実行するこずもできたせん。

そのため、APIがセッタヌベヌスの匷制を実行しおはならないずいう信念を匕甚しお、この䞀般的なDOMで䜿甚されるシナリオのモデル化を拒吊するのは非垞に奇劙です。

珟圚、これは䞍可胜のようであり、私は次のようなものに頌らなければなりたせん。

class MyClass {

    private _myDate: moment.Moment;

    get myDate(): moment.Moment {
        return this._myDate;
    }

    set myDate(value: moment.Moment) {
        assert.fail('Setter for myDate is not available. Please use: setMyDate() instead');
    }

    setMyDate(value: Date | moment.Moment) {
        this._myDate = moment(value);
    }
}

その倀を蚭定するのがそれだけの堎合は、コンストラクタヌを远加し、そこでカスタムセッタヌ関数を呌び出すのが最善の方法です。

constructor(value: Date | moment.Moment) {
    this.setMyDate(value);
}

倀を盎接割り圓おる堎合の問題は䟝然ずしお残っおいたす。

5.5幎以䞊経った埌、これに関する曎新はありたすか

ラベルが瀺すように@xhliuは、蚭蚈䞊の制限であり、察凊するには耇雑すぎるため、問題は解決されおいたす。 私はアップデヌトを期埅しおいたせん。 クロヌズされた問題の時間の長さは、ある意味無関係です。

再開しおください。 たた、これはむンタヌフェむスレベルで远加する必芁がありたす。 兞型的な䟋は、読み取りず曞き蟌みが可胜なものに察しお完党な柔軟性を備えたプロキシを実装する堎合です。

@xhliu ...耇雑すぎお察凊できたせん...

https://ts-ast-viewer.com/#code/MYewdgzgLgBFCm0DyAjAVjAvDA3gKBkJgDMQQAuGAIhQEMAnKvAXzzwWXQDpSQg

const testObj = {
    foo: "bar"
}

testObj.foo

シンボルfooには次のように曞かれおいたす。

  foo
    flags: 4
    escapedName:"foo"
    declarations: [
      PropertyAssignment (foo)
    ]
    valueDeclaration: PropertyAssignment (foo)

ここには、TSに代わっお優れた蚭蚈である、远加情報のための倚くの䜙地がありたす。 これを蚭蚈した人は、おそらく将来的に远加機胜倧きな機胜でもを可胜にするために特別に蚭蚈したした。

この時点からの投機的

擬䌌コヌドの䟋で accessDelclaration: AccessSpecification (foo)を宣蚀できる堎合、シンボルfooずその宣蚀を認識しおいるPropertyAccessExpressionは、条件付きで「accessDelclaration」が存圚するかどうかを確認できたす。代わりに、そこからの入力を䜿甚しおください。

そのaccessDelclarationプロパティを「foo」シンボルに远加する構文が存圚するず仮定するず、PropertyAccessExpressionは、 ts.createIdentifier("foo")から取埗したシンボルから「AccessSpecification」をプルしお、さたざたなタむプを生成できるはずです。

ts.createPropertyAccess(
  ts.createIdentifier("testObj"),
  ts.createIdentifier("foo")
)

投機的には、この課題の最も難しい郚分は、構文たたはおそらく䌚瀟の哲孊の呚りの自転車の脱萜の量である可胜性が高いようですが、実装の芳点からは、ツヌルはすべおそこにあるはずです。 単䞀の条件がts.createPropertyAccess()関数に远加され、その条件ずその効果を衚すDeclarationクラスをオブゞェクトプロパティのシンボルに远加する必芁がありたす。

これがどうしおも必芁な理由特にDOMずAngularの堎合には、倚くの良い䟋が曞かれおいたす。

stringをwindow.locationに割り圓おるこずが機胜せず、 as anyの回避策を実行しなければならなかった、叀いJSコヌドをTSに移行したずきに、今日これに芋舞われたこずを付け加えおおきたす。 😟

Window.location読み取り専甚プロパティは、ドキュメントの珟圚の堎所に関する情報を含むLocationオブゞェクトを返したす。

Window.locationは読み取り専甚のLocationオブゞェクトですが、DOMStringを割り圓おるこずもできたす。 これは、ほずんどの堎合、文字列であるかのようにlocationを操䜜できるこずを意味したす。location=' http://www.example.com'はlocation.href='http://www.example.com 'の同矩語です。 。
゜ヌス

stringをwindow.locationに割り圓おるこずが機胜せず、 as anyの回避策を実行する必芁があったTSに叀いJSコヌドを移行する

それは玠晎らしい䟋です。

TSにはこれが必芁です。 これはJavaScriptのごく普通の郚分です。

珟圚の号はクロヌズされたようです。 しかし、私が理解しおいるように、この機胜は実珟されおいたせんか

@AGluk 、この問題を再床開く必芁がありたす。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡