Skip to content

Commit 178acd9

Browse files
committed
Fixed string completions from generic conditional types that match typed argument against template literal type
1 parent 835fff8 commit 178acd9

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

src/services/stringCompletions.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ function getStringLiteralCompletionsFromSignature(call: CallLikeExpression, arg:
485485
}
486486
}
487487
isNewIdentifier = isNewIdentifier || !!(type.flags & TypeFlags.String);
488-
return getStringLiteralTypes(type, uniques);
488+
return getStringLiteralTypes(type, uniques, arg.text);
489489
});
490490
return length(types) ? { kind: StringLiteralCompletionKind.Types, types, isNewIdentifier } : undefined;
491491
}
@@ -517,11 +517,11 @@ function stringLiteralCompletionsForObjectLiteral(checker: TypeChecker, objectLi
517517
};
518518
}
519519

520-
function getStringLiteralTypes(type: Type | undefined, uniques = new Map<string, true>()): readonly StringLiteralType[] {
520+
function getStringLiteralTypes(type: Type | undefined, uniques = new Map<string, true>(), alreadyTyped = ""): readonly StringLiteralType[] {
521521
if (!type) return emptyArray;
522522
type = skipConstraint(type);
523-
return type.isUnion() ? flatMap(type.types, t => getStringLiteralTypes(t, uniques)) :
524-
type.isStringLiteral() && !(type.flags & TypeFlags.EnumLiteral) && addToSeen(uniques, type.value) ? [type] : emptyArray;
523+
return type.isUnion() ? flatMap(type.types, t => getStringLiteralTypes(t, uniques, alreadyTyped)) :
524+
type.isStringLiteral() && !(type.flags & TypeFlags.EnumLiteral) && type.value.startsWith(alreadyTyped) && addToSeen(uniques, type.value) ? [type] : emptyArray;
525525
}
526526

527527
interface NameAndKind {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @Filename: /a.tsx
4+
//// type PathOf<T, K extends string, P extends string = ""> =
5+
//// K extends `${infer U}.${infer V}`
6+
//// ? U extends keyof T ? PathOf<T[U], V, `${P}${U}.`> : `${P}${keyof T & (string | number)}`
7+
//// : K extends keyof T ? `${P}${K}` : `${P}${keyof T & (string | number)}`;
8+
////
9+
//// declare function consumer<K extends string>(path: PathOf<{a: string, b: {c: string}}, K>) : number;
10+
////
11+
//// consumer('b./*ts*/')
12+
13+
verify.completions({ marker: ["ts"], exact: ["b.c"] });

0 commit comments

Comments
 (0)