Typescript: getterずsetterの異なるアクセス修食子

䜜成日 2015幎04月21日  Â·  40コメント  Â·  ゜ヌス: microsoft/TypeScript

getterずsetterに異なるアクセス修食子を実装するこずは可胜でしょうか このようにしお、セッタヌはたずえばプラむベヌト/保護され、ゲッタヌはパブリックになりたす。 堎合によっおは、倀が読み取り専甚である堎合にこれが非垞に圹立ちたす。

䟋

class MyClass {
    private _myProp: any;
    private set myProp(value: any) {
        this._myProp = value;
    }
    public get myProp(): any {
        return this._myProp;
    }
}
Declined Suggestion Too Complex

最も参考になるコメント

ずにかく、将来再び怜蚎される堎合に備えお、これに+1を远加したす...

党おのコメント40件

12

12は6532でクロヌズされおいるため、この問題は範囲倖のようです。
さたざたなアクセス修食子を実装する蚈画はありたすか
readonlyは、プロパティがクラス内で実際に曞き蟌み可胜である可胜性があるため、ここで説明されおいるこずを解決するには十分ではないためです。

私はたた、私の䟋を関連する問題からここに移すべきだず信じおいたす

declare abstract class Emitter {
    new (): Emitter;
    on: (name:string, handler: (arg:any) => void) => void;
    off: (name:string, handler: (arg:any) => void) => void;
    protected emit: (name:string, arg:any) => void;
}

class Person extends Emitter {
    constructor(name:string) {
        super();
        this.name = name;
    }

    private _name:string;
    get name() {
        return this._name;
    }
    set name(value) {
        if (this._name !== value) {
            this._name = value;
            this.emit('change:name', value);
            //this way is better
            this.updatedAt = new Date();
            //than this way
            this.setUpdatedAt(new Date());
        }
    }

    ////
    private _updatedAt:Date;
    get updatedAt() {
        return this._updatedAt;
    }
    private set updatedAt(value) { //Getter and setter do not agree in visibility
                //some logic and a simple readonly (our absence of a setter) is not enough
        if (this._updatedAt !== value) {
            this._updatedAt = value;
            this.emit('change:updatedAt', value);
        }
    }

    //// method implementation - but what's the point in it?
    private setUpdatedAt(value) {
        if (this._updatedAt !== value) {
            this._updatedAt = value;
            this.emit('change:updatedAt', value);
        }
    }
}

const entity = new Person('Mike');
entity.on('change:updatedAt', console.log.bind(console));
entity.name = 'Thomas';
//but manually setting updatedAt should be forbidden
entity.updatedAt = new Date(); //restricted

ここで、プロパティupdatedAtは実際にはセッタヌを持぀こずができたすが、 Personの倖郚からアクセスできないようにする必芁がありたす。 さらに、このセッタヌには耇雑なロゞックが含たれおおり、単玔な読み取り専甚たたはセッタヌがないだけでは䞍十分です。

プラむベヌトセッタヌは、远加のロゞック攟出などを持぀プラむベヌトメ゜ッドの単なる構文糖衣であるこずに同意したすが、フィヌルドに関連するロゞックの䞀郚がプロパティゲッタヌにあり、別のロゞックの䞀郚がメ゜ッドプラむベヌトセッタヌにある堎合は䞀貫性がないず思いたす。

このように、ゲッタヌ/セッタヌはC#で実装されたす。このコントラクトは実行時に倱われたすが、コンパむル時に異なる可芖性を蚱可するず䟿利だず思いたす。

ここでの掚奚事項は、パブリック読み取り専甚ゲッタヌずプラむベヌト/保護されたバッキングフィヌルドを䜿甚するこずです。

アクセサヌは、型システムのプロパティず察称的です。 私たちが行うこずはすべお、タむプで明瀺され、プロパティで衚珟可胜である必芁がありたす。 private_set / public_getを有効にするために新しいアクセス修食子を远加するず、蚀語ず孊習曲線の耇雑さが増し、これから埗られる倀は、远加された耇雑さず䞀臎したせん。

ずにかく、将来再び怜蚎される堎合に備えお、これに+1を远加したす...

ただ芋たいです。 Cにはそれがあり、倚くの状況で非垞に䟿利です。特に、クラスの倖郚で読み取りたいが、private / protectedで内郚的にのみ蚭定するフラグがある堎合に圹立ちたす。

あたり䜿われおいないずいうのは、パタヌンが䜿えないので䜿わないずいう茶番だず思いたす。

これは蚀語ぞの良い远加ですこれがタむプスクリプトプログラマヌの芳点から远加する耇雑さの量は小さいです。 抂念は理解しやすく、コンパむラヌは、スコヌプが原因でゲッタヌたたはセッタヌにアクセスできない理由を瀺唆する適切な゚ラヌメッセヌゞを提䟛できる必芁がありたす。

私は䞊蚘のナヌザヌに同意したす。これは他のほずんどの蚀語の暙準です。 それに察する議論は重芁ではなく、実装を再怜蚎する必芁がありたす。

私は実際にあなたがTSでこれを行うこずができないこずに驚いおいたした...問題ぞの+1。
これで孊習曲線が増えるこずはないはずです

private get x() { ... }
public set x(value) { ... }

Imo英語が読めるなら、ここでprivateprotected/ publicが䜕を意味するのかは自明です。 たた、そもそもアクセサヌを定矩しおいる堎合、おそらくそれらが䜕のためにあるのかをすでに知っおいるでしょう。

远䌞゚ラヌに぀いお「ゲッタヌずセッタヌのアクセサヌは可芖性に同意したせん」-たあそれはたさに私が圌らにしおもらいたいこずです

これが䟿利な2぀のナヌスケヌスを次に瀺したす。

Backbone.js、醜い.get()ず.set()の呌び出しを避けるために

class Whatever {
    public get rotation(): number {
        return this.get('rotation');
    }
    private set rotation(rotation: number) {
        this.set('rotation', rotation);
    }
}

サブクラスが倉曎できるプロパティ

class ExtendMe {
    public get someProperty(): string {
        // some stuff
    }
    protected set someProperty(prop: string) {
        // some stuff
    }
}

TypeScriptを䜿い始めお以来、私を悩たせおきたので、これを絶察に芋たいず思いたす。

私はこの機胜を芁求する人々に同意したす。 public getメ゜ッドを詊しおみたしたが、セットずgetが可芖性に぀いお合意しおいる必芁があるこずに驚きたした。

耇雑すぎるず䞻匵しお皆さんを読んでいたす。 「C ++の方法」を思い出しお、それが次のものず異なる理由

private _myAttribute: string;
get myAttribute(): string {...}
setMyAttribute(value: string) {...}

私はこれの倚くのナヌスケヌスを芋るこずができたす、それが私が今ここにいる理由です。
myAttributeをパブリックにアクセス可胜にしたいが、そのクラス内でのみ倉曎できるようにするにはどうすればよいですか
属性が倉曎されるたびにカスタムロゞックを远加したい堎合はどうなりたすか
これはビゞネスルヌルである堎合もあれば、デバッグ目的などのブレヌクポむント条件ずずもに、特定の倀が割り圓おられおいる理由を理解するための単なるログである堎合もありたす。

基本的に、メ゜ッドを呌び出すのではなく、倀を割り圓おおいるように芋える構文シュガヌず䞀緒に属性を倉曎するたびに、メ゜ッドを䜿甚する必芁がありたす。
Cにはこのためのプロパティの抂念があり、TSはその抂念を継承しおいるず思いたしたが、異なるアクセシビリティを蚱可しないこずは、私のように考えお「C ++スタむル」にフォヌルバックさせる人々にずっお倧きな制限です。

「難しすぎる」ずいうこずは、信じられないほど䟿利な機胜を実装しない理由にはなりたせん。

私の+1を远加したす。 非垞に倚くの点で完党にこれを行うこずができない蚀語では、私には非垞に奇劙に思えたす。

この問題がクロヌズずしおマヌクされおいるこずに驚いた。 この機胜はコミュニティによっお望たれおいたす。 再開しおください。
+1

12はこの問題に察凊しおいないため、この問題を参照するコメントでこの問題を閉じるべきではありたせん。

私芋これは玠晎らしい機胜ですが、私が理解しおいる限りでは、「私は毎回_propertyを曞きたくないのではなく、プラむベヌトセットプロパティを䜿甚したい」ずいう状況にすぎたせん。

TypeScriptコアコヌド自䜓に非垞に耇雑なものを远加する芚えおおいおください-䞍必芁な耇雑さ-開発の速床が遅くなり、デバッグ、テストの蚘述にかかる時間が長くなりたす-最終的にはリリヌスの頻床が少なくなりたすが、1぀のシンボルの曞き蟌みたたは曞き蟌みを枛らすずいう遞択肢がある堎合その1぀のシンボルずそれをうたく凊理したす...私はむしろ毎回もう䞀床1぀のシンボルを曞きたいです。 結局、私はTSコアの貢献者ではなく、この砂糖の耇雑さの可胜性に察凊したくありたせん。

それは倧したこずではありたせん。 たた、リク゚ストを実装するには耇雑すぎるず刀断するには勇気ず知恵が必芁です結果ずしおコヌド党䜓の耇雑さが増したす。そのため、TypeScriptを開発しおいる皆さんに敬意を衚し、䜜業に感謝したす。

psは、なぜそうしないのかを孊ぶためにここに来たした-結局、私の考えを倉えお、これに察凊したす。_property=..。
そしおただ幞せになりたす

@idchlife setプロパティの目暙は、倀を割り圓おるずきに開発者に1぀のアンダヌスコアを保存するこずではありたせん。 setプロセスにロゞックを远加するこずもできたす。

この号を再床開いおください。 これは明らかに非垞に望たしい機胜です。

+1これが再考されるのを芋たいです。

非垞に奇劙なこずに、他の倚くの蚀語がすでにこれを行っおいる堎合、あなたの論理的根拠は「これは物事を混乱させるでしょう」です。

すべおの👍はあたり機胜しおいないので、もう1぀👍コメントを付けおスパムを送信したす。

これは、物事をより読みやすく、迅速に実装するのに圹立぀構文糖衣です。 倚くの蚀語には、Typescriptを含む構文糖衣構文がありたす。 それをしないずいう本圓の正圓な理由はないようであり、耇雑すぎるこずは決しお䜕かをしない正圓な理由ではありたせん。それは怠惰な譊官のようなものです。 耇雑すぎる問題を解決するこずは、ほずんどの人が゜フトりェア゚ンゞニアリングに惹かれる理由の1぀です。 したがっお、この耇雑な問題を取り䞊げお、それほど耇雑ではない方法で解決しおください。 リファクタリングずリスクの高い倉曎が必芁ですか たぶん、しかしそれは物事が成し遂げられる方法です。

それでも望たしい。 他の蚀語は、get-およびset-機胜の異なる可芖性をサポヌトするのに問題はありたせん。 䟮蟱に負傷を加えるために、TypescriptはCず同じようにMicrosoftによっお䜜成されおいたすが、Cはそれを完党にサポヌトしおいたす。

public string myPropertyWithLimitedAccess { get; private set; }   

あれ芋およ。 矎しく読みやすく、耇雑なこずはたったくありたせん。

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/auto-implemented-properties

サポヌトしない理由はほずんどありたせん。

private _myProperty: string;

public get myProperty(): string { return this._myProperty; }
private set myProperty(value: string) { this._myProperty = value; }

Typescriptは、䞻に.NET開発者がブラりザのフロント゚ンドでの䜜業に慣れるために䜜成されたため、奇劙な蚭蚈䞊の決定にボヌナスポむントがありたす。

+1
Typescriptは間違いなくこの機胜の恩恵を受けるでしょう

TypeScriptはCの埌でも玠晎らしいですが、この無意味な制限は私をかなり頻繁に苛立たせたす。 再床開いおください。

蚀語の耇雑さが増すだろう

readonly [P in keyof T]: T[P]のようなものず比范しお、これは本圓にこの耇雑なものですか

バンプ。 誰もがこの機胜を望んでいたす。 TypesScriptコミュニティが決定するべきではありたせんか

蚀語の耇雑さが増すだろう

readonly [P in keyof T]: T[P]ようなものず比范しお、これは本圓にこの耇雑なものですか

耇雑さは、他の蚀語機胜の盞互䜜甚に関係しおいたす。 残念ながら私はそれを芋぀けるこずができたせんが、IIRC RyanCavanaughは、この機胜を䜿甚しお、クラス匏を䜿甚した継承を介しお䞍倉条件を蚭定し、違反するこずができる䟋を瀺したした。 特定の宣蚀を曞くのが簡単だからずいっお、それが物事にどのように圱響するかを垞に簡単に掚論できるわけではありたせん。

問題は、特定の機胜がどの問題を解決し、どの問題を䜜成するかです。 前者は答えるのが簡単です、埌者は驚くほど答えるのが難しいかもしれたせん。 残念ながら、TSチヌムは、問題を説明するのではなく、「OMGの耇雑さ」で応答するように芋えるこずがありたす。 公平を期すために、n回目のク゚リxぞの回答に費やす時間が長いほど、開発に必芁な時間は少なくなりたす。

実際に蚀語を開発しおいる専門家の間でコンセンサスがあれば、それはあなたに䜕かを教えおくれるはずなので、私は「コミュニティが決定するべきではない」ずいう抂念に100同意したせん。 しかし、私はこのように芁求されたもので、トレヌドオフが䜕であるか、そしおなぜ圌らがそれに反察しおいるのかに぀いおのチヌムからの思慮深い説明を求めるのはそれほど倚くないず思いたす。

そしお個人的には、この堎合のトレヌドオフは1000の䟡倀があるず思いたす。 しかし、わざわざそれを特定しお機胜させるこずができなければ、文句を蚀う暩利はあたりないのではないかず思いたす。

この問題を再怜蚎する良い機䌚でしょうか

readonly修食子は玠晎らしいですが、クラスの内郚で倀を倉曎し、倖郚ですべおを読み取り専甚にしたい堎合が倚くありたす。

プラむベヌトバッキングフィヌルドずプロパティが远加するノむズが気に入らないため、プロパティをreadonlyにしないこずを遞択するこずがよくありたす。

これを行うための構文糖衣があれば玠晎らしいず思いたす。 䜕かのようなもの

// Option 1: C# style
public name: string { get; private set; }

// Option 2: Swift style
private(set) name: string

// Option 3: Swift struct-style
public readonly name: string

mutating changeName(name: string) {
  this.name = name
}

// Option 4: New keyword
public frozen name1: string
public readonly name2: string

私はオプション2が奜きです。それはTypeScript蚀語にうたく適合したす。

オプション3では、 mutatingずしおマヌクされおいる関数の読み取り専甚フィヌルドのみを倉曎できたす。

オプション4では、 frozenはコンストラクタヌでのみ蚭定でき、 readonlyはこのクラスの内郚で蚭定でき、倖郚クラスやこのクラスから継承するクラスでは蚭定できたせん。

参考たでに、より柔軟な修食子に関する@yvbeekのアむデアは、 https//github.com/microsoft/TypeScript/issues/37487での議論に適しおいたす。

この問題は特にゲッタヌずセッタヌ向けであり、非垞に倚くの賛成祚がありたす。 ゲッタヌずセッタヌに異なるアクセス修食子を䞎えるず䟿利だず思いたすTypeScriptチヌムが前進するのに蚱容できるものであるず刀断した堎合は、既存の修食子のセットを37487で曎新できたす

実際に蚀語を開発しおいる専門家の間でコンセンサスがあれば、それはあなたに䜕かを教えおくれるはずなので、私は「コミュニティが決定するべきではない」ずいう抂念に100同意したせん。 しかし、私はこのように芁求されたもので、トレヌドオフが䜕であるか、そしおなぜ圌らがそれに反察しおいるのかに぀いおのチヌムからの思慮深い説明を求めるのはそれほど倚くないず思いたす。

@snarfblam無関係なコメントでこのスレッドを詰たらせないでください、しかしあなたは政府が運営されるべき方法の栞ずなる原則を明らかにしたず思いたす。

この機胜がないこずは私にずっお本圓に苊痛であり、ずりわけTS / NodeJSからもっず...タむプセヌフに切り替えるようになりたした。 それはすべお問題なくダンディですが、倚くのデヌタ構造䜕床も深くネストされおいるを含む耇雑なプロゞェクトで䜜業しおいお、デヌタを適切にモデル化できない堎合、これは「倧芏暡な蚀語」ではないず感じたす。男の子」。

私の特定のケヌスでは、プロパティを読み取り専甚にしたいのですが、内郚から倉曎可胜であり、JSONにシリアル化するこずもできたす。 ゞャンプするにはフヌプが倚すぎたす。

この機胜は、_optionalchaining_ず同じパスをたどる堎合がありたす。 人々は䜕幎もの間この機胜を芁求し、それが実甚的であり、他の蚀語も同じ機胜を提䟛するため、最終的には蚀語に远加されたす。

それ以倖の堎合は、䞀郚の実装がEcmaScriptの䞀郚になり、TypeScriptに移行するこずを期埅しおいたす。

私は最近typescriptに切り替えたばかりで、その蚀語が倧奜きです。 他の蚀語に存圚するこの実甚的な機胜がここに実装されおいないこずに本圓にうんざりしおいたす。 蚀語にどれほど耇雑になるず思われるかに関係なく、将来のリリヌスで远加するこずを再怜蚎しおください。

私はそのようにゲッタヌでcに䌌た䜕かを達成したした

export class I18nService {
  private static ref: I18nService;

  public static get instance(): I18nService {
    if (!I18nService.ref) {
      I18nService.ref = new I18nService();
    }

    return I18nService.ref;
  }
}

次のようなタむプ゚ラヌは理解しやすく、耇雑ではありたせん。

Property 'foo' is writable only in protected scope within class 'Blah' and its subclasses.

たた

Property 'foo' is readable only in protected scope within class 'Blah' and its subclasses.

など、およびprivateず同様です。

それは正盎蚀っお耇雑ではありたせん。

ずころで、私もこの問題に遭遇したした。その間、この皮の「ハック」を䜿甚しおいたす。

// somewhere.ts
declare global {
    type Writable<T> = { -readonly [P in keyof T]: T[P]; }
}

// example.ts
class Example {

    public readonly prop: number;

    public doSomething(n: number): void {
        (this as Writable<this>).prop = n;
    }
}

技術的には、これはどこでも䜿甚できたすが、この回避策の䜿甚は、クラスメ゜ッド内のコヌドに制限する必芁がありたす。

ずころで、私もこの問題に遭遇したした。その間、この皮の「ハック」を䜿甚しおいたす。

私はこのアむデアを自分で詊したしたが、問題は、「パブリック読み取り専甚」プロパティず真の読み取り専甚プロパティを区別する方法がないこずです。 このため、汎甚゜リュヌションずしおはあたり適しおいたせん。

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