Skip to content

Commit 7645e67

Browse files
committed
when the type refer to a single interface, refer to it correctly
Before this change, the following type data Test = TestBlah {x :: Int, y :: Bool} when configured with `tagSingleConstructors = True` would have generated getTypeScriptType (Proxy @test) ==> "Test" formatTSDeclarations (getTypeScriptDeclarations (Proxy @test)) ==> interface TestBlah {x: Int, y: Bool} That is, there would be a dangling references to a non-existent interface `Test`.
1 parent 6ffc83e commit 7645e67

File tree

1 file changed

+10
-9
lines changed
  • src/Data/Aeson/TypeScript

1 file changed

+10
-9
lines changed

src/Data/Aeson/TypeScript/TH.hs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,8 @@ deriveTypeScript options name = do
197197
return [mkInstance (fmap getDatatypePredicate datatypeVars) (AppT (ConT ''TypeScript) (foldl AppT (ConT name) datatypeVars)) [getTypeFn, getParentTypesFn]]
198198
#endif
199199
_ -> do
200-
getTypeFn <- getTypeExpression datatypeInfo >>= \expr -> return $ FunD 'getTypeScriptType [Clause [WildP] (NormalB expr) []]
200+
typeExpr <- getTypeExpression fullyQualifiedDatatypeInfo
201+
let getTypeFn = FunD 'getTypeScriptType [Clause [WildP] (NormalB typeExpr) []]
201202
getDeclarationFn <- getDeclarationFunctionBody options name fullyQualifiedDatatypeInfo typeExpr
202203
getGenericParentTypesFn <- getGenericParentTypesExpression fullyQualifiedDatatypeInfo >>= \expr -> return $ FunD 'getParentTypes [Clause [WildP] (NormalB expr) []]
203204
getNonGenericParentTypesFn <- getNonGenericParentTypesExpression fullyQualifiedDatatypeInfo >>= \expr -> return $ FunD 'getParentTypes [Clause [WildP] (NormalB expr) []]
@@ -225,8 +226,8 @@ getGenericParentTypesExpression (DatatypeInfo {..}) = return $ ListE [AppE (ConE
225226
getNonGenericParentTypesExpression :: DatatypeInfo -> Q Exp
226227
getNonGenericParentTypesExpression (DatatypeInfo {..}) = return $ ListE [AppE (ConE 'TSType) (SigE (ConE 'Proxy) (AppT (ConT ''Proxy) (ConT datatypeName)))]
227228

228-
getDeclarationFunctionBody :: Options -> p -> DatatypeInfo -> Q Dec
229-
getDeclarationFunctionBody options _name datatypeInfo@(DatatypeInfo {..}) = do
229+
getDeclarationFunctionBody :: Options -> p -> DatatypeInfo -> Exp -> Q Dec
230+
getDeclarationFunctionBody options _name datatypeInfo@(DatatypeInfo {..}) nameExpr = do
230231
-- If name is higher-kinded, add generic variables to the type and interface declarations
231232
let genericVariables :: [String] = if | length datatypeVars == 1 -> ["T"]
232233
| otherwise -> ["T" <> show j | j <- [1..(length datatypeVars)]]
@@ -238,8 +239,9 @@ getDeclarationFunctionBody options _name datatypeInfo@(DatatypeInfo {..}) = do
238239

239240
case interfaceNamesAndDeclarations of
240241
[(_, Just interfaceDecl, True)] | datatypeVars == [] -> do
241-
-- The type declaration is just a reference to a single interface, so we can omit the type part and drop the "I" from the interface name
242-
return $ NormalB $ ListE [AppE (VarE 'dropLeadingIFromInterfaceName) interfaceDecl]
242+
-- The type declaration is just a reference to a single interface, so we can omit the type part and replace the interface
243+
-- name with the type name
244+
return $ NormalB $ ListE [AppE (AppE (VarE 'replaceInterfaceName) nameExpr) interfaceDecl]
243245

244246
_ -> do
245247
let interfaceNames = fmap fst3 interfaceNamesAndDeclarations
@@ -249,10 +251,9 @@ getDeclarationFunctionBody options _name datatypeInfo@(DatatypeInfo {..}) = do
249251

250252
return $ FunD 'getTypeScriptDeclarations [Clause [WildP] declarationFnBody []]
251253

252-
dropLeadingIFromInterfaceName :: TSDeclaration -> TSDeclaration
253-
dropLeadingIFromInterfaceName decl@(TSInterfaceDeclaration {interfaceName=('I':xs)}) = decl { interfaceName = xs }
254-
dropLeadingIFromInterfaceName decl@(TSTypeAlternatives {typeName=('I':xs)}) = decl { typeName = xs }
255-
dropLeadingIFromInterfaceName x = x
254+
replaceInterfaceName :: String -> TSDeclaration -> TSDeclaration
255+
replaceInterfaceName name decl@(TSInterfaceDeclaration {}) = decl { interfaceName = name }
256+
replaceInterfaceName name decl@(TSTypeAlternatives {}) = decl { typeName = name }
256257

257258
-- | Return a string to go in the top-level type declaration, plus an optional expression containing a declaration
258259
handleConstructor :: Options -> DatatypeInfo -> [String] -> ConstructorInfo -> (Exp, Maybe Exp, Bool)

0 commit comments

Comments
 (0)