diff --git a/src/Data/Aeson/TypeScript/Instances.hs b/src/Data/Aeson/TypeScript/Instances.hs index 988aec0..9f33c84 100644 --- a/src/Data/Aeson/TypeScript/Instances.hs +++ b/src/Data/Aeson/TypeScript/Instances.hs @@ -100,6 +100,14 @@ instance TypeScript Word32 where instance TypeScript Word64 where getTypeScriptType _ = "number" +-- | Get TypeScript type with null handling for optional types +getTypeScriptTypeWithNull :: forall a. TypeScript a => Proxy a -> String +getTypeScriptTypeWithNull p = + let baseType = getTypeScriptType p + in if getTypeScriptOptional p + then baseType <> " | null" + else baseType + instance {-# OVERLAPPABLE #-} (TypeScript a) => TypeScript [a] where getTypeScriptType _ = (getTypeScriptType (Proxy :: Proxy a)) ++ "[]" getParentTypes _ = [TSType (Proxy :: Proxy a)] @@ -122,20 +130,20 @@ instance (TypeScript a, TypeScript b) => TypeScript (Either a b) where ] instance (TypeScript a, TypeScript b) => TypeScript (a, b) where - getTypeScriptType _ = [i|[#{getTypeScriptType (Proxy :: Proxy a)}, #{getTypeScriptType (Proxy :: Proxy b)}]|] + getTypeScriptType _ = [i|[#{getTypeScriptTypeWithNull (Proxy :: Proxy a)}, #{getTypeScriptTypeWithNull (Proxy :: Proxy b)}]|] getParentTypes _ = L.nub [ (TSType (Proxy :: Proxy a)) , (TSType (Proxy :: Proxy b)) ] instance (TypeScript a, TypeScript b, TypeScript c) => TypeScript (a, b, c) where - getTypeScriptType _ = [i|[#{getTypeScriptType (Proxy :: Proxy a)}, #{getTypeScriptType (Proxy :: Proxy b)}, #{getTypeScriptType (Proxy :: Proxy c)}]|] + getTypeScriptType _ = [i|[#{getTypeScriptTypeWithNull (Proxy :: Proxy a)}, #{getTypeScriptTypeWithNull (Proxy :: Proxy b)}, #{getTypeScriptTypeWithNull (Proxy :: Proxy c)}]|] getParentTypes _ = L.nub [ (TSType (Proxy :: Proxy a)) , (TSType (Proxy :: Proxy b)) , (TSType (Proxy :: Proxy c)) ] instance (TypeScript a, TypeScript b, TypeScript c, TypeScript d) => TypeScript (a, b, c, d) where - getTypeScriptType _ = [i|[#{getTypeScriptType (Proxy :: Proxy a)}, #{getTypeScriptType (Proxy :: Proxy b)}, #{getTypeScriptType (Proxy :: Proxy c)}, #{getTypeScriptType (Proxy :: Proxy d)}]|] + getTypeScriptType _ = [i|[#{getTypeScriptTypeWithNull (Proxy :: Proxy a)}, #{getTypeScriptTypeWithNull (Proxy :: Proxy b)}, #{getTypeScriptTypeWithNull (Proxy :: Proxy c)}, #{getTypeScriptTypeWithNull (Proxy :: Proxy d)}]|] getParentTypes _ = L.nub [ (TSType (Proxy :: Proxy a)) , (TSType (Proxy :: Proxy b)) , (TSType (Proxy :: Proxy c)) diff --git a/test/Generic.hs b/test/Generic.hs index ea6d05b..463aab8 100644 --- a/test/Generic.hs +++ b/test/Generic.hs @@ -25,6 +25,13 @@ $(deriveTypeScript defaultOptions ''Complex3) data Complex4 k = Product4 { record4 :: Map Text k } $(deriveTypeScript defaultOptions ''Complex4) +-- Test for Maybe inside tuple +data TestMaybeTuple + = ConWithMaybe Text [Int] (Maybe [String]) + | SimpleConstructor Text + deriving (Show, Eq) +$(deriveTypeScript defaultOptions ''TestMaybeTuple) + tests :: SpecWith () tests = describe "Generic instances" $ do it [i|Complex makes the declaration and types correctly|] $ do @@ -57,5 +64,12 @@ tests = describe "Generic instances" $ do ,TSTypeAlternatives "Complex4" ["T"] ["IProduct4"] Nothing ] + it [i|TestMaybeTuple should handle Maybe in tuples correctly|] $ do + (getTypeScriptDeclarationsRecursively (Proxy :: Proxy TestMaybeTuple)) `shouldBe` [ + TSInterfaceDeclaration "IConWithMaybe" [] [TSField False "tag" "\"ConWithMaybe\"" Nothing, TSField False "contents" "[string, number[], string[] | null]" Nothing] Nothing + ,TSInterfaceDeclaration "ISimpleConstructor" [] [TSField False "tag" "\"SimpleConstructor\"" Nothing, TSField False "contents" "string" Nothing] Nothing + ,TSTypeAlternatives "TestMaybeTuple" [] ["IConWithMaybe","ISimpleConstructor"] Nothing + ] + main :: IO () main = hspec tests