From 4beef64259d92a2b311af2006666fdbaebeea355 Mon Sep 17 00:00:00 2001 From: Landon Gavin Date: Tue, 2 Jan 2024 19:23:50 -0500 Subject: [PATCH] patch(return types): union return type with undefined. React query data is undefined by default. Previously we were overriding the default type of react query. Now union with undefined. We are also exporting the data type. --- src/createUseQuery.ts | 419 ++++++++++++++++++++++-------------------- 1 file changed, 224 insertions(+), 195 deletions(-) diff --git a/src/createUseQuery.ts b/src/createUseQuery.ts index 90dde10..bee4373 100644 --- a/src/createUseQuery.ts +++ b/src/createUseQuery.ts @@ -43,10 +43,7 @@ export const createUseQuery = ( const customHookName = `use${className}${capitalizeFirstLetter(methodName)}`; const queryKey = `${customHookName}Key`; - const queryKeyGenericType = ts.factory.createTypeReferenceNode( - "TQueryKey", - undefined - ); + const queryKeyGenericType = ts.factory.createTypeReferenceNode("TQueryKey"); const queryKeyConstraint = ts.factory.createTypeReferenceNode("Array", [ ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword), ]); @@ -69,219 +66,251 @@ export const createUseQuery = ( ), ] ); + // DefaultResponseDataType + const defaultApiResponse = ts.factory.createTypeAliasDeclaration( + [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], + ts.factory.createIdentifier( + `${capitalizeFirstLetter(className)}${capitalizeFirstLetter( + methodName + )}DefaultResponse` + ), + undefined, + awaitedResponseDataType + ); + + const TData = ts.factory.createIdentifier("TData"); + const TError = ts.factory.createIdentifier("TError"); const responseDataType = ts.factory.createTypeParameterDeclaration( undefined, - "TData", + TData.text, undefined, - awaitedResponseDataType + ts.factory.createTypeReferenceNode(defaultApiResponse.name) ); - return [ - // QueryKey - ts.factory.createVariableStatement( - [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], - ts.factory.createVariableDeclarationList( + // Omit>, TError>, 'data'> & { data: TData|undefined }; + const responseReturnType = ts.factory.createIntersectionTypeNode([ + ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("Omit"), [ + ts.factory.createTypeReferenceNode( + ts.factory.createIdentifier("UseQueryResult"), [ - ts.factory.createVariableDeclaration( - ts.factory.createIdentifier(queryKey), - undefined, - undefined, - ts.factory.createStringLiteral( - `${className}${capitalizeFirstLetter(methodName)}` - ) - ), - ], - ts.NodeFlags.Const - ) + defaultApiResponse.type, + ts.factory.createTypeReferenceNode(TError, undefined), + ] + ), + ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral("data")), + ]), + ts.factory.createTypeLiteralNode([ + ts.factory.createPropertySignature( + undefined, + ts.factory.createIdentifier("data"), + undefined, + ts.factory.createUnionTypeNode([ + ts.factory.createTypeReferenceNode(TData, undefined), + ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword), + ]) + ), + ]), + ]); + + // Return Type + const returnTypeExport = ts.factory.createTypeAliasDeclaration( + [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], + ts.factory.createIdentifier( + `${capitalizeFirstLetter(className)}${capitalizeFirstLetter( + methodName + )}QueryResult` ), - // Custom hook - ts.factory.createVariableStatement( - [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], - ts.factory.createVariableDeclarationList( - [ - ts.factory.createVariableDeclaration( - ts.factory.createIdentifier(customHookName), - undefined, + [ + ts.factory.createTypeParameterDeclaration( + undefined, + TData, + undefined, + ts.factory.createTypeReferenceNode(defaultApiResponse.name) + ), + ts.factory.createTypeParameterDeclaration( + undefined, + TError, + undefined, + ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword) + ), + ], + responseReturnType + ); + + // QueryKey + const queryKeyExport = ts.factory.createVariableStatement( + [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], + ts.factory.createVariableDeclarationList( + [ + ts.factory.createVariableDeclaration( + ts.factory.createIdentifier(queryKey), + undefined, + undefined, + ts.factory.createStringLiteral( + `${className}${capitalizeFirstLetter(methodName)}` + ) + ), + ], + ts.NodeFlags.Const + ) + ); + + // Custom hook + const hookExport = ts.factory.createVariableStatement( + [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], + ts.factory.createVariableDeclarationList( + [ + ts.factory.createVariableDeclaration( + ts.factory.createIdentifier(customHookName), + undefined, + undefined, + ts.factory.createArrowFunction( undefined, - ts.factory.createArrowFunction( - undefined, - ts.factory.createNodeArray([ - ts.factory.createTypeParameterDeclaration( - undefined, - "TQueryKey", - queryKeyConstraint, - ts.factory.createArrayTypeNode( - ts.factory.createKeywordTypeNode( - ts.SyntaxKind.UnknownKeyword - ) - ) - ), - responseDataType, - ts.factory.createTypeParameterDeclaration( - undefined, - "TError", - undefined, + ts.factory.createNodeArray([ + ts.factory.createTypeParameterDeclaration( + undefined, + "TQueryKey", + queryKeyConstraint, + ts.factory.createArrayTypeNode( ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword) - ), - ]), - [ - ...requestParam, - ts.factory.createParameterDeclaration( - undefined, - undefined, - ts.factory.createIdentifier("queryKey"), - ts.factory.createToken(ts.SyntaxKind.QuestionToken), - queryKeyGenericType - ), - ts.factory.createParameterDeclaration( - undefined, - undefined, - ts.factory.createIdentifier("options"), - ts.factory.createToken(ts.SyntaxKind.QuestionToken), - ts.factory.createTypeReferenceNode( - ts.factory.createIdentifier("Omit"), - [ - ts.factory.createTypeReferenceNode( - ts.factory.createIdentifier("UseQueryOptions"), - [ - awaitedResponseDataType, - ts.factory.createKeywordTypeNode( - ts.SyntaxKind.UnknownKeyword - ), - awaitedResponseDataType, - ts.factory.createArrayTypeNode( - ts.factory.createKeywordTypeNode( - ts.SyntaxKind.UnknownKeyword - ) - ), - ] - ), - ts.factory.createUnionTypeNode([ - ts.factory.createLiteralTypeNode( - ts.factory.createStringLiteral("queryKey") - ), - ts.factory.createLiteralTypeNode( - ts.factory.createStringLiteral("queryFn") - ), - ts.factory.createLiteralTypeNode( - ts.factory.createStringLiteral("initialData") - ), - ]), - ] - ) - ), - ], - undefined, - ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), - ts.factory.createAsExpression( - ts.factory.createCallExpression( - ts.factory.createIdentifier("useQuery"), - undefined, + ) + ), + responseDataType, + ts.factory.createTypeParameterDeclaration( + undefined, + TError, + undefined, + ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword) + ), + ]), + [ + ...requestParam, + ts.factory.createParameterDeclaration( + undefined, + undefined, + ts.factory.createIdentifier("queryKey"), + ts.factory.createToken(ts.SyntaxKind.QuestionToken), + queryKeyGenericType + ), + ts.factory.createParameterDeclaration( + undefined, + undefined, + ts.factory.createIdentifier("options"), + ts.factory.createToken(ts.SyntaxKind.QuestionToken), + ts.factory.createTypeReferenceNode( + ts.factory.createIdentifier("Omit"), [ - ts.factory.createObjectLiteralExpression([ - ts.factory.createPropertyAssignment( - ts.factory.createIdentifier("queryKey"), - ts.factory.createArrayLiteralExpression( - [ - ts.factory.createIdentifier(queryKey), - ts.factory.createSpreadElement( - ts.factory.createParenthesizedExpression( - ts.factory.createBinaryExpression( - ts.factory.createIdentifier("queryKey"), - ts.factory.createToken( - ts.SyntaxKind.QuestionQuestionToken - ), - method.parameters.length - ? ts.factory.createArrayLiteralExpression([ - ts.factory.createObjectLiteralExpression( - method.parameters.map((param) => - ts.factory.createShorthandPropertyAssignment( - ts.factory.createIdentifier( - param.name.getText(node) - ) - ) - ) - ), - ]) - : ts.factory.createArrayLiteralExpression( - [] - ) - ) - ) - ), - ], - false - ) + ts.factory.createTypeReferenceNode( + ts.factory.createIdentifier("UseQueryOptions"), + [ + ts.factory.createTypeReferenceNode(TData), + ts.factory.createTypeReferenceNode(TError), + ts.factory.createTypeReferenceNode(TData), + queryKeyGenericType, + ] + ), + ts.factory.createUnionTypeNode([ + ts.factory.createLiteralTypeNode( + ts.factory.createStringLiteral("queryKey") ), - ts.factory.createPropertyAssignment( - ts.factory.createIdentifier("queryFn"), - ts.factory.createArrowFunction( - undefined, - undefined, - [], - undefined, - ts.factory.createToken( - ts.SyntaxKind.EqualsGreaterThanToken - ), - ts.factory.createCallExpression( - ts.factory.createPropertyAccessExpression( - ts.factory.createIdentifier(className), - ts.factory.createIdentifier(methodName) - ), - undefined, - method.parameters.map((param) => - ts.factory.createIdentifier( - param.name.getText(node) - ) - ) - ) - ) + ts.factory.createLiteralTypeNode( + ts.factory.createStringLiteral("queryFn") ), - ts.factory.createSpreadAssignment( - ts.factory.createIdentifier("options") + ts.factory.createLiteralTypeNode( + ts.factory.createStringLiteral("initialData") ), ]), ] - ), - // Omit>, TError>, 'data'> & { data: TData }; - ts.factory.createIntersectionTypeNode([ - ts.factory.createTypeReferenceNode( - ts.factory.createIdentifier("Omit"), - [ - ts.factory.createTypeReferenceNode( - ts.factory.createIdentifier("UseQueryResult"), + ) + ), + ], + undefined, + ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), + ts.factory.createCallExpression( + ts.factory.createIdentifier("useQuery"), + [ + ts.factory.createTypeReferenceNode(TData), + ts.factory.createTypeReferenceNode(TError), + ts.factory.createTypeReferenceNode(TData), + queryKeyGenericType, + ], + [ + ts.factory.createObjectLiteralExpression([ + ts.factory.createPropertyAssignment( + ts.factory.createIdentifier("queryKey"), + ts.factory.createAsExpression( + ts.factory.createArrayLiteralExpression( [ - awaitedResponseDataType, - ts.factory.createTypeReferenceNode( - ts.factory.createIdentifier("TError"), - undefined + ts.factory.createIdentifier(queryKey), + ts.factory.createSpreadElement( + ts.factory.createParenthesizedExpression( + ts.factory.createBinaryExpression( + ts.factory.createIdentifier("queryKey"), + ts.factory.createToken( + ts.SyntaxKind.QuestionQuestionToken + ), + method.parameters.length + ? ts.factory.createArrayLiteralExpression([ + ts.factory.createObjectLiteralExpression( + method.parameters.map((param) => + ts.factory.createShorthandPropertyAssignment( + ts.factory.createIdentifier( + param.name.getText(node) + ) + ) + ) + ), + ]) + : ts.factory.createArrayLiteralExpression([]) + ) + ) ), - ] - ), - ts.factory.createLiteralTypeNode( - ts.factory.createStringLiteral("data") + ], + false ), - ] + queryKeyGenericType + ) ), - ts.factory.createTypeLiteralNode([ - ts.factory.createPropertySignature( + ts.factory.createPropertyAssignment( + ts.factory.createIdentifier("queryFn"), + ts.factory.createArrowFunction( + undefined, undefined, - ts.factory.createIdentifier("data"), + [], undefined, - ts.factory.createTypeReferenceNode( - ts.factory.createIdentifier("TData"), - undefined + ts.factory.createToken( + ts.SyntaxKind.EqualsGreaterThanToken + ), + ts.factory.createAsExpression( + ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(className), + ts.factory.createIdentifier(methodName) + ), + undefined, + method.parameters.map((param) => + ts.factory.createIdentifier( + param.name.getText(node) + ) + ) + ), + ts.factory.createTypeReferenceNode(TData) ) - ), - ]), - ]) - ) + ) + ), + ts.factory.createSpreadAssignment( + ts.factory.createIdentifier("options") + ), + ]), + ] ) - ), - ], - ts.NodeFlags.Const - ) - ), - ]; + ) + ), + ], + ts.NodeFlags.Const + ) + ); + + return [defaultApiResponse, returnTypeExport, queryKeyExport, hookExport]; };