Closed vcanadi closed 3 years ago
Oh, after some recent changes you need to include the type parameter. So Proxy :: Proxy (D T)
or Proxy :: Proxy (HigherKind T)
. For multiple params you can do T1
, T2
, etc. Sorry, I need to update the docs.
Thanks. I noticed that this is the intended usage from the tests, but I was unsure since I didn't manage to get it working in my code (not the one mentioned above). What I need is a higher kinded type parameter. e.g.
data X f = X (f Int)
Is this possible?
Yes, it's possible as long as when you call getTypeScriptDeclarations
you fill in f
with something such that you get a reasonable type to map to TypeScript. For example, see the tests in TypeFamilies.hs
under the heading "Complicated Beam-like user type".
Somewhat related to this, there is special built-in support for type families, when get mapped to TypeScript lookup types. You can also see that in the TypeFamilies.hs
tests, somewhat mixed together with the other higher kinded stuff. I need to write that up properly as well.
Could you write an simple example of what to pass to my X
type for f
argument in getTypeScriptDeclaratios? I tried making a type TtoT
similar to yours T
, but I didn't manage to get it to work.
data X f = X (f Int)
$(deriveTypeScript A.defaultOptions ''X)
-- Unfortunately we need to declare this funny instance because the constraints on
-- getTypeScriptDeclarations are a little too tight in this case
instance TypeScript (HashMap String) where
getTypeScriptType _ = "void"
decls = getTypeScriptDeclarations (Proxy :: Proxy (X (HashMap String)))
> putStrLn $ formatTSDeclarations decls
type X = IX;
type IX = {[k: string]: number};
So is this something like making and typescript type for a "subtype" Y of X where
type Y = X (HashMap String)
but HashMap String
is arbitrarily chosen and it could be any * -> *
type like Identity
or Maybe
as well?
As I understood, now the f
as a type argument doesn't exist in TS? So it's just like a type without an argument, but I got to chose the specification (HashMap String) in Proxy (X (HashMap String)))
it possible that f
remains unchosen so it remains a higher level type argument (or some hacky equivalent of it) in the TS?
My ultimate goal is to have this type in haskell:
data AlterList a b c d n = AlterList (a n) [(b n, c n)] (d n) (c n)
and have the TS equivalent without worrying to much about the TS (which I am not very familiar with)
The part where you want f
to remain unchosen sounds like you might want the closed type family stuff:
type family MyTypeFamily a = result | result -> a where
MyTypeFamily Int = String
MyTypeFamily String = Bool
MyTypeFamily T = Int
data X a = X (MyTypeFamily a)
$(deriveTypeScript' A.defaultOptions ''X (ExtraTypeScriptOptions { typeFamiliesToMapToTypeScript = [''MyTypeFamily] }))
decls = getTypeScriptDeclarationsRecursively (Proxy :: Proxy (X T))
> putStrLn $ formatTSDeclarations decls
interface MyTypeFamily {
number: string;
string: boolean;
T: number;
}
type IX<T extends keyof MyTypeFamily> = MyTypeFamily[T];
type X<T extends keyof MyTypeFamily> = IX<T>;
In general, TypeScript has a less powerful type system than Haskell, so it's hard to map your AlterList
to TS generally, without knowing more about what a, b, c, d can be. But presumably you're also coming up with FromJSON
/ToJSON
instances, so that might help narrow down the types. (For example, a n
couldn't be a function type.)
I updated the docs so I'm going to close this now, but feel free to let me know if you have any other questions.
The example with type
D
doesn't seem to work on the type alone (without given type params). Similar behaviour (same error) happens with more simple example from tests:which results in: