Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
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.
  • Loading branch information
sandersn committed Jul 27, 2016
commit a6642d68c92ce7ddd16e8da71a1f2eb909fde74d
2 changes: 2 additions & 0 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5326,6 +5326,8 @@ namespace ts {
return getTypeFromThisTypeNode(node);
case SyntaxKind.StringLiteralType:
return getTypeFromStringLiteralTypeNode(<StringLiteralTypeNode>node);
case SyntaxKind.JSDocStringLiteralType:
return getTypeFromStringLiteralTypeNode((<JSDocStringLiteralType>node).stringLiteral);
case SyntaxKind.TypeReference:
case SyntaxKind.JSDocTypeReference:
return getTypeFromTypeReference(<TypeReferenceNode>node);
Expand Down
9 changes: 8 additions & 1 deletion src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5860,9 +5860,10 @@ namespace ts {
case SyntaxKind.SymbolKeyword:
case SyntaxKind.VoidKeyword:
return parseTokenNode<JSDocType>();
case SyntaxKind.StringLiteral:
return parseJSDocStringLiteralType();
}

// TODO (drosen): Parse string literal types in JSDoc as well.
return parseJSDocTypeReference();
}

Expand Down Expand Up @@ -6041,6 +6042,12 @@ namespace ts {
return finishNode(result);
}

function parseJSDocStringLiteralType(): JSDocStringLiteralType {
const result = <JSDocStringLiteralType>createNode(SyntaxKind.JSDocStringLiteralType);
result.stringLiteral = parseStringLiteralTypeNode();
return finishNode(result);
}

function parseJSDocUnknownOrNullableType(): JSDocUnknownType | JSDocNullableType {
const pos = scanner.getStartPos();
// skip the ?
Expand Down
5 changes: 5 additions & 0 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ namespace ts {
JSDocTypedefTag,
JSDocPropertyTag,
JSDocTypeLiteral,
JSDocStringLiteralType,

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may need to update the LastJSDocNode and LastJSDocTagNode pointers

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

// Synthesized list
SyntaxList,
Expand Down Expand Up @@ -1491,6 +1492,10 @@ namespace ts {
type: JSDocType;
}

export interface JSDocStringLiteralType extends JSDocType {
stringLiteral: StringLiteralTypeNode;
}

export type JSDocTypeReferencingNode = JSDocThisType | JSDocConstructorType | JSDocVariadicType | JSDocOptionalType | JSDocNullableType | JSDocNonNullableType;

// @kind(SyntaxKind.JSDocRecordMember)
Expand Down
16 changes: 16 additions & 0 deletions tests/baselines/reference/jsdocStringLiteral.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//// [in.js]
/**
* @param {'literal'} input
*/
function f(input) {
return input + '.';
}


//// [out.js]
/**
* @param {'literal'} input
*/
function f(input) {
return input + '.';
}
12 changes: 12 additions & 0 deletions tests/baselines/reference/jsdocStringLiteral.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
=== tests/cases/compiler/in.js ===
/**
* @param {'literal'} input
*/
function f(input) {
>f : Symbol(f, Decl(in.js, 0, 0))
>input : Symbol(input, Decl(in.js, 3, 11))

return input + '.';
>input : Symbol(input, Decl(in.js, 3, 11))
}

14 changes: 14 additions & 0 deletions tests/baselines/reference/jsdocStringLiteral.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
=== tests/cases/compiler/in.js ===
/**
* @param {'literal'} input
*/
function f(input) {
>f : (input: "literal") => string
>input : "literal"

return input + '.';
>input + '.' : string
>input : "literal"
>'.' : string
}

12 changes: 12 additions & 0 deletions tests/cases/conformance/jsdoc/jsdocStringLiteral.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// @allowJs: true
// @filename: in.js
// @out: out.js
/**
* @param {'literal'} p1
* @param {"literal"} p2
* @param {'literal' | 'other'} p3
* @param {'literal' | number} p4
*/
function f(p1, p2, p3, p4) {
return p1 + p2 + p3 + p4 + '.';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this test really do anything apart from test baselines? Why not write some tests that have observable characteristics from a usage standpoint?

For instance, string completion when calling something that takes a union type of string literals.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea to add a string-literal-specific test. I didn't even know that we offered completions in strings.

This test checks that the jsdoc parser gets the types right. It's in a JavaScript file so the parameter types would otherwise be any. That will produce a lot of observable differences in parameter help and quick info. But I trust those work if the checker can get the types right.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.
Hilariously, @Filename is case-sensitive in fourslash tests, but not compiler and conformance tests.
Also, Codeflow has two Give Feedback buttons, and they are not the same -- one is the inverse colour of the other.
OK, I'm done complaining now.

}