[キー:文字列]を検索する


このシリーズでは、私は野生で遭遇した混乱と風変わりなもののいくつかをメモするつもりです.それで、今日、私はタイプスクリプトでこのスニペットを始めます.

動機
interface CustomState {
  value: {
    [key:string]: any
  }
}

const defaultState : CustomState = {
  value: {}
}

const reducer = (state: CustomState, action: { type: string }): CustomState => {
  if (action.type === 'reset') {
    return {
      value: []
    }
  } else {
    return {
      ...state
    }
  }
}
The CustomState 開始時に宣言されたプロパティvalue , フォームのキー値ペアを持つオブジェクトですstring - any . The defaultState 変数は、上で宣言されたインターフェースに合っている(空の)オブジェクトを含みます.
私を追い払ったものは、還元器にあります.還元機能は、状態をクリアすることによって状態をリセットすることになっていますvalue プロパティ.しかし、ここでは、配列[] の代わりに{} .
私は、タイプからの変化を考えましたobject 活かすarray 特にJavaと比較すれば、とてもドラマチックですHashMapArrayList それと同じように?これも可能ですか?)この奇妙な部分は、タイプスクリプトにはまったくこれについての気質がなかったということでした.いいえカーリーラインやコンパイラの警告.

探査
私が最初にしたことは、インターフェイスが正しく宣言されたかどうかを調べることでしたvalue オブジェクトまたは配列を含みます.これによりインデックス署名の定義を確認できました.

インデックス
インデックス署名は、可能な値の型を記述する方法です.公式タイプスクリプトドキュメントで使用される例を借りる
interface StringArray {
    [index: number]: string;
}

const myArray: StringArray = getStringArray();
const secondItem = myArray[1]; // secondItem is of type string
インデックス署名を宣言する構文は、最初は奇妙に思えるかもしれません.オブジェクトを宣言するように見えます{} 上記の例では、配列のインターフェイスを宣言するために使用します.比較のために、オブジェクトインタフェースを宣言する方法は次のようになります.
interface PaintOptions {
  xPos: number;
  yPos: number;
}
TypeScriptのドキュメント例では、インデックス署名を使用して配列を記述します.しかし、以下のような線もあります.

While string index signatures are a powerful way to describe the “dictionary” pattern, they also enforce that all properties match their return type.


もう少し詳細な調査を行うことで、インデックス署名がオブジェクトに対してどのように適用できるかについての他の例を示します.
interface NumberDictionary {
  [index: string]: number;
  length: number;
  width: number;
}
だからCustomState , 以下のどちらも正しいです.
const arrayExample:CustomState = {
  value: [{val: 1}]
}

const objectExample:CustomState = {
  value: {val: 1}
}

配列対オブジェクト
私がチェックした2番目のことは{} に置き換えられます[] , 配列とオブジェクトは、もう一つのユースケースについて既に知っていること以外に、JavaScript/typescriptで同じことですか?この質問にあまり深くいかないと、コンソールログで観測できます.
console.log(typeof []) // "object"
console.log(typeof {}) // "object"

スタックオーバーフロー?
この記事の例を作成し始め、このスタックオーバーフローに遭遇したとき、興味のある最後のビットが現れましたquestion . 本質的に、その人は問題を抱えていたIndex signature of object type implicitly has an 'any' type . さらに下にスクロールすると、提案されたanswer 最初の例と同じようなものがありました.
type ISomeType = {[key: string]: any};

    let someObject: ISomeType = {
        firstKey:   'firstValue',
        secondKey:  'secondValue',
        thirdKey:   'thirdValue'
    };

    let key: string = 'secondKey';

    let secondValue: string = someObject[key];
実際には、宣言するISomeType 次のように動作します.
type ISomeType = {[key: string]: any};

// My additional example
let someArray: ISomeType = [
    {firstKey:   'firstValue'},
    {secondKey:  'secondValue'},
    {thirdKey:   'thirdValue'}
]

let newkey: string = 'secondKey';

let newSecondValue: string = someArray[newkey];
しかし、使用の場合any が置き換えられた場合、全体が壊れます.
// Note the change in the type and therefore the error!
type ISomeTypeA = {[key: string]: string};

let someObjectA: ISomeTypeA = {
    firstKey:   'firstValue',
    secondKey:  'secondValue',
    thirdKey:   'thirdValue'
};

let keyA: string = 'secondKey';

let secondValueA: string = someObjectA[keyA];

// My additional example
let someArrayA: ISomeTypeA = [  // Error: Type '{ firstKey: string; }' is not 
    {firstKey:   'firstValue'}, // assignable to type 'string'.
    {secondKey:  'secondValue'},
    {thirdKey:   'thirdValue'}
]

let newkeyA: string = 'secondKey';

let newSecondValueA: string = someArrayA[newkeyA];
物語の潜在的なモラル?使わないany 😂

資源
この記事で使用されるコードスニペットもTypeScript playground .