Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9199dd9

Browse files
alan-agius4thePunderWoman
authored andcommitted
docs(docs-infra): update default generic values and add constraints for type parameters in functions (#58548)
Before ```typescript createNodeRequestHandler( handler: T ): T; ``` ```typescript class NgIf<T> { @input() set ngIf(value: T); @input() set ngIfThen(value: TemplateRef<NgIfContext<T>> | null); @input() set ngIfElse(value: TemplateRef<NgIfContext<T>> | null); static ngTemplateGuard_ngIf: "binding"; static ngTemplateContextGuard<T>(dir: NgIf<T>, ctx: any): boolean; } ``` Now ```typescript createNodeRequestHandler<T extends NodeRequestHandlerFunction>( handler: T ): T; ``` ```typescript class NgIf<T = unknown> { @input() set ngIf(value: T); @input() set ngIfThen(value: TemplateRef<NgIfContext<T>> | null); @input() set ngIfElse(value: TemplateRef<NgIfContext<T>> | null); static ngTemplateGuard_ngIf: "binding"; static ngTemplateContextGuard<T>(dir: NgIf<T>, ctx: any): boolean; } ``` PR Close #58548
1 parent 5a236c2 commit 9199dd9

File tree

2 files changed

+106
-7
lines changed

2 files changed

+106
-7
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import {makeGenericsText} from '../../transforms/code-transforms';
2+
3+
describe('makeGenericsText', () => {
4+
it('should return an empty string if no generics are provided', () => {
5+
expect(makeGenericsText(undefined)).toBe('');
6+
expect(makeGenericsText([])).toBe('');
7+
});
8+
9+
it('should return a single generic type without constraints or default', () => {
10+
const generics = [{name: 'T', constraint: undefined, default: undefined}];
11+
expect(makeGenericsText(generics)).toBe('<T>');
12+
});
13+
14+
it('should handle a single generic type with a constraint', () => {
15+
const generics = [{name: 'T', constraint: 'string', default: undefined}];
16+
expect(makeGenericsText(generics)).toBe('<T extends string>');
17+
});
18+
19+
it('should handle a single generic type with a default value', () => {
20+
const generics = [{name: 'T', default: 'number', constraint: undefined}];
21+
expect(makeGenericsText(generics)).toBe('<T = number>');
22+
});
23+
24+
it('should handle a single generic type with both constraint and default value', () => {
25+
const generics = [{name: 'T', constraint: 'string', default: 'number'}];
26+
expect(makeGenericsText(generics)).toBe('<T extends string = number>');
27+
});
28+
29+
it('should handle multiple generic types without constraints or defaults', () => {
30+
const generics = [
31+
{name: 'T', constraint: undefined, default: undefined},
32+
{name: 'U', constraint: undefined, default: undefined},
33+
];
34+
expect(makeGenericsText(generics)).toBe('<T, U>');
35+
});
36+
37+
it('should handle multiple generic types with constraints and defaults', () => {
38+
const generics = [
39+
{name: 'T', constraint: 'string', default: 'number'},
40+
{name: 'U', constraint: 'boolean', default: undefined},
41+
{name: 'V', default: 'any', constraint: undefined},
42+
];
43+
expect(makeGenericsText(generics)).toBe(
44+
'<T extends string = number, U extends boolean, V = any>',
45+
);
46+
});
47+
48+
it('should handle complex generics with mixed constraints and defaults', () => {
49+
const generics = [
50+
{name: 'A', constraint: 'string', default: undefined},
51+
{name: 'B', constraint: undefined, default: undefined},
52+
{name: 'C', default: 'number', constraint: undefined},
53+
{name: 'D', constraint: 'boolean', default: 'true'},
54+
];
55+
expect(makeGenericsText(generics)).toBe(
56+
'<A extends string, B, C = number, D extends boolean = true>',
57+
);
58+
});
59+
});

‎adev/shared-docs/pipeline/api-gen/rendering/transforms/code-transforms.ts

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import {
1010
DocEntry,
1111
FunctionSignatureMetadata,
12+
GenericEntry,
1213
MemberEntry,
1314
MemberTags,
1415
ParameterEntry,
@@ -332,8 +333,10 @@ function getMethodCodeLine(
332333
displayParamsInNewLines: boolean = false,
333334
isFunction: boolean = false,
334335
): string {
336+
const generics = makeGenericsText(member.generics);
337+
335338
displayParamsInNewLines &&= member.params.length > 0;
336-
return `${isFunction ? 'function' : ''}${memberTags.join(' ')} ${member.name}(${displayParamsInNewLines ? '\n ' : ''}${member.params
339+
return `${isFunction ? 'function' : ''}${memberTags.join(' ')} ${member.name}${generics}(${displayParamsInNewLines ? '\n ' : ''}${member.params
337340
.map((param) => mapParamEntry(param))
338341
.join(`,${displayParamsInNewLines ? '\n ' : ' '}`)}${
339342
displayParamsInNewLines ? '\n' : ''
@@ -442,12 +445,7 @@ function appendPrefixAndSuffix(entry: DocEntry, codeTocData: CodeTableOfContents
442445
};
443446

444447
if (isClassEntry(entry) || isInterfaceEntry(entry)) {
445-
const generics =
446-
entry.generics?.length > 0
447-
? `<${entry.generics
448-
.map((g) => (g.constraint ? `${g.name} extends ${g.constraint}` : g.name))
449-
.join(', ')}>`
450-
: '';
448+
const generics = makeGenericsText(entry.generics);
451449

452450
const extendsStr = entry.extends ? ` extends ${entry.extends}` : '';
453451
// TODO: remove the ? when we distinguish Class & Decorator entries
@@ -501,3 +499,45 @@ export function addApiLinksToHtml(htmlString: string): string {
501499

502500
return result;
503501
}
502+
503+
/**
504+
* Constructs a TypeScript generics string based on an array of generic type entries.
505+
*
506+
* This function takes an array of generic type entries and returns a formatted string
507+
* representing TypeScript generics syntax, including any constraints and default values
508+
* specified in each entry.
509+
*
510+
* @param generics - An array of `GenericEntry` objects representing the generics to be formatted,
511+
* or `undefined` if there are no generics.
512+
*
513+
* @returns A formatted string representing TypeScript generics syntax, or an empty string if no generics are provided.
514+
*/
515+
export function makeGenericsText(generics: GenericEntry[] | undefined): string {
516+
if (!generics?.length) {
517+
return '';
518+
}
519+
520+
const parts: string[] = ['<'];
521+
522+
for (let index = 0; index < generics.length; index++) {
523+
const {constraint, default: defaultVal, name} = generics[index];
524+
525+
parts.push(name);
526+
527+
if (constraint) {
528+
parts.push(' extends ', constraint);
529+
}
530+
531+
if (defaultVal !== undefined) {
532+
parts.push(' = ', defaultVal);
533+
}
534+
535+
if (index < generics.length - 1) {
536+
parts.push(', ');
537+
}
538+
}
539+
540+
parts.push('>');
541+
542+
return parts.join('');
543+
}

0 commit comments

Comments
 (0)