2017-10-26 11 views
3

の内側に失敗し活字タイプのマッピングは、これらの活字体の種類を考えると、一般的な機能

// Data object, holding the form submission 
const data: Fields = { 
    firstName: 'John', 
    lastname: 'Doe', 
    e: '[email protected]' 
} 

// Map validation methods to the data fields 
const mapping: Mapping<Fields> = [ 
    'firstName', 
    'lastname', 
    { 
    e: 'email' 
    } 
] 

なぜこの作品:

const validationFuncs: Method<Fields>[] = mapping.map(m => { 
    return typeof m === 'string' ? { [m]: m } : m; 
}) 

// validationFuncs[0].firstName // works 

しかしこのdoesnの't?

function validate<T>(mapping: Mapping<T>) { 
    const validationFuncs: Method<T>[] = mapping.map(m => { 
    return typeof m === 'string' ? { [m]: m } : m; 
    }) 
} 

Why?

+0

どのタイプのTypeScriptを使用していますか?新しいバージョンでは、いくつかのより厳しいジェネリックチェックが導入されました。 – msanford

+1

Typescript 2.5.3 –

答えて

2

Method<T>の値のみ"firstName""lastName"、又は"email"ことができるMethods、でなければなりません。あなたの一般的な例では:

function validate<T>(mapping: Mapping<T>) { 
    const validationFuncs: Method<T>[] = mapping.map(m => { 
    return typeof m === 'string' ? { [m]: m } : m; 
    }) 
} 

タイプTは、例えば何も...、{nope: string}することができます。この場合、keyof T"nope"であり、validationFuncsの宣言型は{nope?: Methods}[]です。

しかしmappingは(有効Mapping<{nope: string}>["nope"]であれば、その後validationFuncsは、実行時に[{nope: "nope"}]になります。しかし、がundefinedの代わりに"nope"であるか、またはMethodsの3つの許容値のいずれかではなく、{nope?: Methods}[]ではありません。コンパイラはそれについて警告します。これはすべて私にとって理にかなっています。

あなたの非ジェネリックで

、たとえば "ワーキング":奇妙な何かが起こっている

const validationFuncs: Method<Fields>[] = mapping.map(m => { 
    return typeof m === 'string' ? { [m]: m } : m; 
}) 

を。 Method<Fields>

type MethodFields = { 
    firstName?: Methods 
    lastname?: Methods 
    e?: Methods 
} 

しかし活字体2.6にfixedである場合があります{ [m]: m }isn't working properly because of a TypeScript bug with computed keysの型チェックと同等です。わからない。

コンパイラ(のではなく)が{ [m]: m }のみない有効Method<Fields>要素は(lastnameで小文字の「n」を気づか)されている最後の2つは{firstName:"firstName"}{lastname:"lastname"}、または{e:"e"}、であることが保証されていることを認識すべきです。その代わりに、型チェッカーは{ [m]: m }の型を{ [k: string]: keyof Fields }のように広げます。これは明らかに、Method<Fields>と一致するように十分に幅がありますが、私は理解できません。とにかく、それはタイプしないでください。 TypeScriptのバグやデザイン上の制限です。


どちらの場合も、宣言した型に準拠するようにコードを実装していません。あなたのタイプが正しいかどうかは分かりませんが、実装が間違っているかどうか、あるいはその逆かどうかはわかりません。進歩を遂げるのに十分な情報があることを願っています。がんばろう!

+0

ありがとう@jcalz、素晴らしい答え。私は最終的に同じ結論に達しましたが、不一致を理解できませんでした。私は最初のTypescriptプロジェクトにわずか数時間しかいませんし、このような問題を抱えています。バグのように見えるものもあれば、私の最後の実装であるものもあります。これは、多くのおかげで、ありがとう。 –

関連する問題