2017-10-31 4 views
1

オブジェクトインデックスの署名を設定しようとすると、重複インデックス番号の署名にエラーが発生しました。ここでは、実際には同じシグネチャを持つオブジェクトを追加するため、2人のオブジェクトの署名を必要としない作業例click heretypescriptのインデックス署名はどのように機能しますか?

export class HelloComponent implements OnInit { 
     //works 
     watched: { [id: number]: boolean } = {} ; //works 
     //doesnt work 
     watchedOne: { [id: number]: boolean, 
     [fid: number]: boolean } = {} ; // Doesn't Work 
     constructor() {} 

     watch(talk): void { 
     console.log('watch', talk.id); 
     this.watched[talk.id] = true; 
     this.watchedOne[talk.id] = true; // error 
     console.log('watch-obj', this.watched); 
    } 
    ngOnInit() { 
     this.watch({ 
      id: 9, 
      fid: 4 
     }); 
    } 
    } 
+0

'watchedOne'で達成しようとしているのは、2つのインデックスシグネチャが必要だと思いますか?あなたの例では、 'this.watch()'に渡されたオブジェクトの 'fid'プロパティで何もしません。あなたはこのコードが何をすると思いますか? – jcalz

+0

[このコード](https://stackblitz.com/edit/angular-vkxnlr?file=app%2Fhello.component.ts)は、あなたが望むように動作しますか?もしそうなら、私はその周りに答えを作ります。 – jcalz

+0

インデックスシグニチャを使用する方法を知っておく必要があります。2〜3つの例を作成して、どのように動作するかを教えてください。 – Karty

答えて

2

The TypeScript Handbookおよび/またはTypeScript Deep Diveにインデックス署名のセクションをお読みください。

おそらくそこには明示的ではありません。なぜインデックスシグニチャが必要ですか?タイプを定義したい場合に、キー名を含めて気になるプロパティのセットを知っている場合は、インデックスの署名は必要ありません。誰かがインデックス署名せずにオブジェクトにアクセスし、未知のキーを使用して、または未知のキーを持つリテラル新鮮なオブジェクトを割り当てるときは、コンパイラエラーです:

const foo: {bar: boolean, baz: boolean} = { 
    bar: true, 
    baz: false, 
    qux: false // error, extra property not expected 
}; 
foo.bar; 
foo.baz; 
foo.qux; // error, no idea what qux is supposed to be 
foo.quux; // error, no idea what quux is supposed to be 
上記のコードで

barbaz受け入れられますが、 quxにエラーがあります。あなたに設定することができ、単一のインデックス署名で

const foo: {bar: boolean, baz: boolean, [k: string]: boolean | undefined} = { 
    bar: true, 
    baz: false, 
    qux: false // no error 
}; 
foo.bar; 
foo.baz; 
foo.qux; // boolean | undefined 
foo.quux; // boolean | undefined 

:、代わりに、あなたはそれがどうなるか事前に知らなくても、任意のキーをできるようにしたい場合は

、あなたはインデックスの署名を追加することができますキーと値の適切なタイプの多くのプロパティを必要に応じて。署名にインデックスキーを付ける名前はまったく重要ではありません。正しいタイプの任意のキーのプレースホルダです。キーの2つのタイプは、stringnumberです。インデックス署名でkは問題ではないこと

const foo: { [k: number]: boolean | undefined } = { }; 
foo[0] = true; 
foo[1] = false; 
foo[2] = void 0; // undefined 
foo[12345] = true; 
foo[54321] = false; 
foo[1.5] = true; 
foo[-4] = false; 

注:単一numberインデックスを使用して、例えば

、。私は通常kを使用しますが、それは問題ではないので、keyまたはrandomなどを使用できます。単なるプレースホルダです。私はこのような何かを行うことによって、あなたの上記のコードを動作させることができることを意味し


export class HelloComponent implements OnInit { 
    name: string = "karty"; 
    watched: { [id: number]: boolean } = {} ; 
    // single index signature 
    watchedOne: { [id: number]: boolean } = {} ; 
    constructor() {} 

    // type annotation on talk to ensure the right types 
    watch(talk: {id: number, fid: number}): void { 
    console.log('watch', talk.id); 
    this.watched[talk.id] = true; 
    this.watchedOne[talk.fid] = true; 
    console.log('watch-obj', this.watched); 
} 
ngOnInit() { 
    this.watch({ 
     id: 9, 
     fid: 4 
    }); 
} 
} 

お役に立てば幸いです。がんばろう!

1

です。しかし、異なる署名を持つオブジェクトを追加する必要がある場合は、宣言に異なる署名を追加する必要があります。

以下は、異なる署名の宣言を含むスニペットの例です。この例のスニペットは、番号とwatchedOne変数に文字列を持つことができます(文字列が数値を包含しているため、以下の@Jcalzのコメントを参照してください)

export class HelloComponent implements OnInit { 
    //works 
    watched: { [id: number]: boolean } = {} ; //works 
    //works now 
    watchedOne: {[fid: string]: boolean } = {} ; // Here variable name(like fid) doesn't really matter 
    constructor() {} 

    watch(talk): void { 
    console.log('watch', talk.id); 
    this.watched[talk.id] = true; 
    this.watchedOne[talk.id] = true; // no error here now 
    this.watchedOne[talk.fid] = true; //no error , 
    this.watchedOne[talk.str] = true; //no error 
    console.log('watch-obj', this.watched); 
    console.log('watch-one-obj', this.watchedOne); // this works fine 
} 
ngOnInit() { 
    this.watch({ 
     id: 9, 
     fid: 4, 
     str:"hello" 
    }); 
} 
} 
+0

「異なるタイプのオブジェクト」と言うとき、どういう意味ですか?この答えから明らかなように、2つのインデックスシグネチャを実行する唯一の方法は、 'string'キー用と' number'キー用の両方の場合です。両方を指定すると、 'number'のプロパティ値キーは 'string'キーのプロパティ値の* subtype *である必要があります。どちらも 'ブール型'であれば問題ありませんが、不要です。 – jcalz

+0

watchedOneに2つの数値型がないのはなぜですか? – Karty

+0

@Jcalz - 私はそれに応じて私の答えを編集しました。私はここで特定の場合を指していた –

関連する問題