2016-09-13 9 views
1

タプルの和集合型は、次の例の関数パスで各ケースを手作業で指定しなくても、コードパスの型制約を満たすことができますか?タプル連合型の制御フロー解析

type options = 
    [string, (a:string) => number] 
    | [number, (b:number) => string ] 

function f([input,fn]: options) { 
    // Error: Cannot invoke an expression which lacks a call signature 
    return fn(input) 
} 

inputstringであれば、fnstringを受け入れる、とinputnumberであれば、fnnumberを受け入れます。それでも、Typescriptは、string | numberと考えてfnは入力を受け入れることができないと考えています。

可能な機能は(string) => number | (number) => stringです。ここで入力はstring | numberです。受け入れられた機能が(string|number) => number | (string|number) => stringのtypecriptであれば問題ありません。しかし、私はTypescriptに、がargを受け入れることができないという方法がないことを伝えたいと思います(これは本当です)。

私はTypescriptが個々のタイプが互換性がないと判断している理由を理解しています。しかし、私はtypescriptに各可能なタプルが自己完結型であることを伝える方法を探しており、独自の関数で独自のargを呼び出すことができます。

+0

私に正しい行動があるようですか? 'f'はタプルを受け取り、それに文字列や数値を与えようとしていますか? –

+0

'f(入力)'を 'fn(入力)'にする必要がありますか? – mrmcgreg

+0

最後の段落に 'f'ではなく' fn'と書かれているので、彼はええと思います。彼が得たエラーは 'f'を呼び出すためのものなので、質問の誤字ではありません。私はこの意図を反映するために私の答えを修正しました。このバグを修正するには、やや複雑な型理論のためにまだ失敗するでしょう。私はこれがおもちゃの例か、あなたが実際に使いたいものかどうか疑問に思いますか? –

答えて

2

これを機能させるにはタイプセーフな方法があります。 asキーワードがキャストされていない場合は、となります。タイプに互換性がない場合は文句を言います。

type options = 
    [string, (a:string) => number] 
    | [number, (b:number) => string ] 

function f([input,fn]: options) { 
    return (fn as (a: string | number) => string | number)(input); 
} 

活字体は、それ自体で、このいずれかを把握するために十分にスマートではありませんので、タイプに少しだけを広げて少しの助けを必要とします。

+0

はい、それは動作する全く異なる例です。元の質問では、コールバックを呼び出さずに再帰的に呼び出していることに注意してください。 –

+0

ああ、私はそれを誤解しています。ありがとう! – mrmcgreg

+0

多分、私の答えを修正します。 –