Return string completions for indexed access types

This commit is contained in:
Marius Schulz 2017-12-30 09:40:53 +01:00
parent 4eb633e0d9
commit 25c5e57091
5 changed files with 31 additions and 8 deletions

View file

@ -4403,7 +4403,7 @@ namespace ts {
return node.kind === SyntaxKind.RegularExpressionLiteral;
}
export function isNoSubstitutionTemplateLiteral(node: Node): node is LiteralExpression {
export function isNoSubstitutionTemplateLiteral(node: Node): node is NoSubstitutionTemplateLiteral {
return node.kind === SyntaxKind.NoSubstitutionTemplateLiteral;
}

View file

@ -264,7 +264,8 @@ namespace ts.Completions {
// }
// let a: A;
// a['/*completion position*/']
return getStringLiteralCompletionEntriesFromElementAccess(node.parent, typeChecker, compilerOptions.target, log);
const type = typeChecker.getTypeAtLocation(node.parent.expression);
return getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(node, type, typeChecker, compilerOptions.target, log);
}
else if (node.parent.kind === SyntaxKind.ImportDeclaration || node.parent.kind === SyntaxKind.ExportDeclaration
|| isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false) || isImportCall(node.parent)
@ -278,6 +279,16 @@ namespace ts.Completions {
const entries = PathCompletions.getStringLiteralCompletionsFromModuleNames(node, compilerOptions, host, typeChecker);
return pathCompletionsInfo(entries);
}
else if (isIndexedAccessTypeNode(node.parent.parent)) {
// Get all apparent property names
// i.e. interface Foo {
// foo: string;
// bar: string;
// }
// let x: Foo["/*completion position*/"]
const type = typeChecker.getTypeFromTypeNode(node.parent.parent.objectType);
return getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(node, type, typeChecker, compilerOptions.target, log);
}
else {
const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile);
if (argumentInfo) {
@ -334,11 +345,10 @@ namespace ts.Completions {
return undefined;
}
function getStringLiteralCompletionEntriesFromElementAccess(node: ElementAccessExpression, typeChecker: TypeChecker, target: ScriptTarget, log: Log): CompletionInfo | undefined {
const type = typeChecker.getTypeAtLocation(node.expression);
function getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(stringLiteralNode: StringLiteral | NoSubstitutionTemplateLiteral, type: Type, typeChecker: TypeChecker, target: ScriptTarget, log: Log): CompletionInfo | undefined {
const entries: CompletionEntry[] = [];
if (type) {
getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, node, /*performCharacterChecks*/ false, typeChecker, target, log, /*allowStringLiteral*/ true);
getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, stringLiteralNode, /*performCharacterChecks*/ false, typeChecker, target, log, /*allowStringLiteral*/ true);
if (entries.length) {
return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries };
}
@ -1583,7 +1593,7 @@ namespace ts.Completions {
switch (contextToken.kind) {
case SyntaxKind.OpenParenToken:
case SyntaxKind.CommaToken:
return isConstructorDeclaration(contextToken.parent) && contextToken.parent;
return isConstructorDeclaration(contextToken.parent) && contextToken.parent;
default:
if (isConstructorParameterCompletion(contextToken)) {

View file

@ -2911,7 +2911,7 @@ declare namespace ts {
function isStringLiteral(node: Node): node is StringLiteral;
function isJsxText(node: Node): node is JsxText;
function isRegularExpressionLiteral(node: Node): node is RegularExpressionLiteral;
function isNoSubstitutionTemplateLiteral(node: Node): node is LiteralExpression;
function isNoSubstitutionTemplateLiteral(node: Node): node is NoSubstitutionTemplateLiteral;
function isTemplateHead(node: Node): node is TemplateHead;
function isTemplateMiddle(node: Node): node is TemplateMiddle;
function isTemplateTail(node: Node): node is TemplateTail;

View file

@ -2964,7 +2964,7 @@ declare namespace ts {
function isStringLiteral(node: Node): node is StringLiteral;
function isJsxText(node: Node): node is JsxText;
function isRegularExpressionLiteral(node: Node): node is RegularExpressionLiteral;
function isNoSubstitutionTemplateLiteral(node: Node): node is LiteralExpression;
function isNoSubstitutionTemplateLiteral(node: Node): node is NoSubstitutionTemplateLiteral;
function isTemplateHead(node: Node): node is TemplateHead;
function isTemplateMiddle(node: Node): node is TemplateMiddle;
function isTemplateTail(node: Node): node is TemplateTail;

View file

@ -0,0 +1,13 @@
/// <reference path='fourslash.ts'/>
////interface Foo {
//// foo: string;
//// bar: string;
////}
////
////let x: Foo["/*1*/"]
goTo.marker("1");
verify.completionListContains("foo");
verify.completionListContains("bar");
verify.completionListCount(2);