reinforced-typings

ReinforcedTypings RtDictionaryType substitution


I try to use Microsoft.FSharp.Collections.FSharpMap (standrad Map in F#) in my model. It implements

System.Collections.Generic.IReadOnlyDictionary<TKey, TValue> 

and

System.Collections.Generic.IReadOnlyCollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>

so it is a Dictionary type. Unfortunately ReinforcedTypings gives me this warning:

Type resolvation warning RT0003: Could not find suitable TypeScript type for System.Collections.Generic.KeyValuePair`2[[System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[BkkFutar.Data.BKKApi.RouteReference, BkkFutarCore.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]. 'any' assumed

It looks like it identifies as an IReadOnlyCollection<KeyValuePair<K, V>> and not as a dictionary.

I also tried to use

Substitute(typeof(FSharpMap<,>),` new RtDictionaryType())

in the configuration but it does not work. On the other hand

Substitute(typeof(FSharpMap<string,string>), new RtDictionaryType(new RtSimpleTypeName("string"), new RtSimpleTypeName("string")))

does work but I dont want nor can specify every case.


Solution

  • You have to use SubstituteGeneric instead:

    SubstituteGeneric(typeof(FSharpMap<,>), (t, tr) =>
    {
        var args = t.GetGenericArguments();
        return new RtDictionaryType(tr.ResolveTypeName(args[0]),tr.ResolveTypeName(args[1]));
    })
    

    I've made corresponding unit test especially for you. :)

    It seems to be internal RT's... inconvenience, not a bug per se. RT detects dictionaries by implemented IDictionary<,> interface first and then, if not succeded, it tries to find IEnumerables in type. That is why you've got warning about KeyValuePair<,>: FSharpMap implements IEnumerable<> of them.

    The IDictionary<,> interface represents actually mutable hashmap that contains Add method. IReadOnlyDictionary appeared in .NET a bit later than early versions of RT were made.

    By the way it is not correct to resolve IReadOnlyDictionary to TypeScript's hash object because this one actually IS mutable. But anyway I will consider this improvement for next versions of RT.