Skip to content

Commit a6642d6

Browse files
committed
JSDoc understands string literal types
Unfortunately, I didn't find a way to reuse the normal string literal type, so I had to extend the existing JSDoc type hierarchy. Otherwise, this feature is very simple.
1 parent c578367 commit a6642d6

File tree

7 files changed

+69
-1
lines changed

7 files changed

+69
-1
lines changed

src/compiler/checker.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5326,6 +5326,8 @@ namespace ts {
53265326
return getTypeFromThisTypeNode(node);
53275327
case SyntaxKind.StringLiteralType:
53285328
return getTypeFromStringLiteralTypeNode(<StringLiteralTypeNode>node);
5329+
case SyntaxKind.JSDocStringLiteralType:
5330+
return getTypeFromStringLiteralTypeNode((<JSDocStringLiteralType>node).stringLiteral);
53295331
case SyntaxKind.TypeReference:
53305332
case SyntaxKind.JSDocTypeReference:
53315333
return getTypeFromTypeReference(<TypeReferenceNode>node);

src/compiler/parser.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5860,9 +5860,10 @@ namespace ts {
58605860
case SyntaxKind.SymbolKeyword:
58615861
case SyntaxKind.VoidKeyword:
58625862
return parseTokenNode<JSDocType>();
5863+
case SyntaxKind.StringLiteral:
5864+
return parseJSDocStringLiteralType();
58635865
}
58645866

5865-
// TODO (drosen): Parse string literal types in JSDoc as well.
58665867
return parseJSDocTypeReference();
58675868
}
58685869

@@ -6041,6 +6042,12 @@ namespace ts {
60416042
return finishNode(result);
60426043
}
60436044

6045+
function parseJSDocStringLiteralType(): JSDocStringLiteralType {
6046+
const result = <JSDocStringLiteralType>createNode(SyntaxKind.JSDocStringLiteralType);
6047+
result.stringLiteral = parseStringLiteralTypeNode();
6048+
return finishNode(result);
6049+
}
6050+
60446051
function parseJSDocUnknownOrNullableType(): JSDocUnknownType | JSDocNullableType {
60456052
const pos = scanner.getStartPos();
60466053
// skip the ?

src/compiler/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ namespace ts {
346346
JSDocTypedefTag,
347347
JSDocPropertyTag,
348348
JSDocTypeLiteral,
349+
JSDocStringLiteralType,
349350

350351
// Synthesized list
351352
SyntaxList,
@@ -1491,6 +1492,10 @@ namespace ts {
14911492
type: JSDocType;
14921493
}
14931494

1495+
export interface JSDocStringLiteralType extends JSDocType {
1496+
stringLiteral: StringLiteralTypeNode;
1497+
}
1498+
14941499
export type JSDocTypeReferencingNode = JSDocThisType | JSDocConstructorType | JSDocVariadicType | JSDocOptionalType | JSDocNullableType | JSDocNonNullableType;
14951500

14961501
// @kind(SyntaxKind.JSDocRecordMember)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//// [in.js]
2+
/**
3+
* @param {'literal'} input
4+
*/
5+
function f(input) {
6+
return input + '.';
7+
}
8+
9+
10+
//// [out.js]
11+
/**
12+
* @param {'literal'} input
13+
*/
14+
function f(input) {
15+
return input + '.';
16+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
=== tests/cases/compiler/in.js ===
2+
/**
3+
* @param {'literal'} input
4+
*/
5+
function f(input) {
6+
>f : Symbol(f, Decl(in.js, 0, 0))
7+
>input : Symbol(input, Decl(in.js, 3, 11))
8+
9+
return input + '.';
10+
>input : Symbol(input, Decl(in.js, 3, 11))
11+
}
12+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
=== tests/cases/compiler/in.js ===
2+
/**
3+
* @param {'literal'} input
4+
*/
5+
function f(input) {
6+
>f : (input: "literal") => string
7+
>input : "literal"
8+
9+
return input + '.';
10+
>input + '.' : string
11+
>input : "literal"
12+
>'.' : string
13+
}
14+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// @allowJs: true
2+
// @filename: in.js
3+
// @out: out.js
4+
/**
5+
* @param {'literal'} p1
6+
* @param {"literal"} p2
7+
* @param {'literal' | 'other'} p3
8+
* @param {'literal' | number} p4
9+
*/
10+
function f(p1, p2, p3, p4) {
11+
return p1 + p2 + p3 + p4 + '.';
12+
}

0 commit comments

Comments
 (0)