Skip to content

Commit 1323ab1

Browse files
JeanMechepkozlowski-opensource
authored andcommitted
refactor(compiler-cli): Extract type predicates from type guards. (angular#60934)
Previously they were extracted as `boolean`. PR Close angular#60934
1 parent 3d86b3a commit 1323ab1

2 files changed

Lines changed: 30 additions & 14 deletions

File tree

packages/compiler-cli/src/ngtsc/docs/src/function_extractor.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,7 @@ export class FunctionExtractor {
3232
// TODO: is there any real situation in which the signature would not be available here?
3333
// Is void a better type?
3434
const signature = this.typeChecker.getSignatureFromDeclaration(this.exportDeclaration);
35-
const returnType = signature
36-
? this.typeChecker.typeToString(
37-
this.typeChecker.getReturnTypeOfSignature(signature),
38-
undefined,
39-
// This ensures that e.g. `T | undefined` is not reduced to `T`.
40-
ts.TypeFormatFlags.NoTypeReduction | ts.TypeFormatFlags.NoTruncation,
41-
)
42-
: 'unknown';
35+
const returnType = signature ? extractReturnType(signature, this.typeChecker) : 'unknown';
4336

4437
const implementation =
4538
findImplementationOfFunction(this.exportDeclaration, this.typeChecker) ??
@@ -149,15 +142,24 @@ export function extractCallSignatures(name: string, typeChecker: ts.TypeChecker,
149142
jsdocTags: extractJsDocTags(decl),
150143
params: extractAllParams(decl.parameters, typeChecker),
151144
rawComment: extractRawJsDoc(decl),
152-
returnType: typeChecker.typeToString(
153-
typeChecker.getReturnTypeOfSignature(signature),
154-
undefined,
155-
// This ensures that e.g. `T | undefined` is not reduced to `T`.
156-
ts.TypeFormatFlags.NoTypeReduction | ts.TypeFormatFlags.NoTruncation,
157-
),
145+
returnType: extractReturnType(signature, typeChecker),
158146
}));
159147
}
160148

149+
function extractReturnType(signature: ts.Signature, typeChecker: ts.TypeChecker): string {
150+
// Handling Type Predicates
151+
if (signature?.declaration?.type && ts.isTypePredicateNode(signature.declaration.type)) {
152+
return signature.declaration.type.getText();
153+
}
154+
155+
return typeChecker.typeToString(
156+
typeChecker.getReturnTypeOfSignature(signature),
157+
undefined,
158+
// This ensures that e.g. `T | undefined` is not reduced to `T`.
159+
ts.TypeFormatFlags.NoTypeReduction | ts.TypeFormatFlags.NoTruncation,
160+
);
161+
}
162+
161163
/** Finds the implementation of the given function declaration overload signature. */
162164
export function findImplementationOfFunction(
163165
node: FunctionLike,

packages/compiler-cli/test/ngtsc/doc_extraction/function_doc_extraction_spec.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,5 +145,19 @@ runInEachFileSystem(() => {
145145
expect(genericEntry.constraint).toBeUndefined();
146146
expect(genericEntry.default).toBeUndefined();
147147
});
148+
149+
it('should extract type predicates as return type of type guards', () => {
150+
env.write(
151+
'index.ts',
152+
`export function isSignal(value: unknown): value is Signal<unknown> {}`,
153+
);
154+
155+
const docs: DocEntry[] = env.driveDocsExtraction('index.ts');
156+
expect(docs.length).toBe(1);
157+
158+
const [functionEntry] = docs as FunctionEntry[];
159+
expect(functionEntry.implementation.returnType).toBe('value is Signal<unknown>');
160+
expect(functionEntry.signatures[0].returnType).toBe('value is Signal<unknown>');
161+
});
148162
});
149163
});

0 commit comments

Comments
 (0)