@@ -4462,10 +4462,12 @@ namespace ts {
4462
4462
}
4463
4463
if (type.flags & TypeFlags.Template) {
4464
4464
const texts = (<TemplateType>type).texts;
4465
+ const casings = (<TemplateType>type).casings;
4465
4466
const types = (<TemplateType>type).types;
4466
4467
const templateHead = factory.createTemplateHead(texts[0]);
4467
4468
const templateSpans = factory.createNodeArray(
4468
4469
map(types, (t, i) => factory.createTemplateTypeSpan(
4470
+ casings[i],
4469
4471
typeToTypeNodeHelper(t, context),
4470
4472
(i < types.length - 1 ? factory.createTemplateMiddle : factory.createTemplateTail)(texts[i + 1]))));
4471
4473
context.approximateLength += 2;
@@ -10864,7 +10866,7 @@ namespace ts {
10864
10866
if (t.flags & TypeFlags.Template) {
10865
10867
const types = (<TemplateType>t).types;
10866
10868
const constraints = mapDefined(types, getBaseConstraint);
10867
- return constraints.length === types.length ? getTemplateType((<TemplateType>t).texts, constraints) : stringType;
10869
+ return constraints.length === types.length ? getTemplateType((<TemplateType>t).texts, (<TemplateType>t).casings, constraints) : stringType;
10868
10870
}
10869
10871
if (t.flags & TypeFlags.IndexedAccess) {
10870
10872
const baseObjectType = getBaseConstraint((<IndexedAccessType>t).objectType);
@@ -13396,32 +13398,28 @@ namespace ts {
13396
13398
if (!links.resolvedType) {
13397
13399
links.resolvedType = getTemplateType(
13398
13400
[node.head.text, ...map(node.templateSpans, span => span.literal.text)],
13401
+ map(node.templateSpans, span => span.casing),
13399
13402
map(node.templateSpans, span => getTypeFromTypeNode(span.type)));
13400
13403
}
13401
13404
return links.resolvedType;
13402
13405
}
13403
13406
13404
- function getTemplateType(texts: readonly string[], types: readonly Type[]): Type {
13407
+ function getTemplateType(texts: readonly string[], casings: readonly TemplateCasing[], types: readonly Type[]): Type {
13405
13408
const unionIndex = findIndex(types, t => !!(t.flags & (TypeFlags.Never | TypeFlags.Union)));
13406
13409
if (unionIndex >= 0) {
13407
13410
return checkCrossProductUnion(types) ?
13408
- mapType(types[unionIndex], t => getTemplateType(texts, replaceElement(types, unionIndex, t))) :
13411
+ mapType(types[unionIndex], t => getTemplateType(texts, casings, replaceElement(types, unionIndex, t))) :
13409
13412
errorType;
13410
13413
}
13411
13414
let i = 0;
13412
13415
while (i < types.length) {
13413
13416
const t = types[i];
13414
13417
if (t.flags & TypeFlags.Literal) {
13415
- const s = getTemplateStringForType(t) || "";
13418
+ const s = applyTemplateCasing( getTemplateStringForType(t) || "", casings[i]) ;
13416
13419
texts = [...texts.slice(0, i), texts[i] + s + texts[i + 1], ...texts.slice(i + 2)];
13420
+ casings = [...casings.slice(0, i), ...casings.slice(i + 1)];
13417
13421
types = [...types.slice(0, i), ...types.slice(i + 1)];
13418
13422
}
13419
- else if (t.flags & TypeFlags.Template) {
13420
- const ts = (<TemplateType>t).texts;
13421
- texts = [...texts.slice(0, i), texts[i] + ts[0], ...ts.slice(1, -1), ts[ts.length - 1] + texts[i + 1], ...texts.slice(i + 2)];
13422
- types = [...types.slice(0, i), ...(<TemplateType>t).types, ...types.slice(i + 1)];
13423
- i += (<TemplateType>t).types.length;
13424
- }
13425
13423
else if (isGenericIndexType(t)) {
13426
13424
i++;
13427
13425
}
@@ -13432,10 +13430,10 @@ namespace ts {
13432
13430
if (types.length === 0) {
13433
13431
return getLiteralType(texts[0]);
13434
13432
}
13435
- const id = `${getTypeListId(types)}|${map(texts, t => t.length).join(",")}|${texts.join("")}`;
13433
+ const id = `${getTypeListId(types)}|${casings.join(",")}|${ map(texts, t => t.length).join(",")}|${texts.join("")}`;
13436
13434
let type = templateTypes.get(id);
13437
13435
if (!type) {
13438
- templateTypes.set(id, type = createTemplateType(texts, types));
13436
+ templateTypes.set(id, type = createTemplateType(texts, casings, types));
13439
13437
}
13440
13438
return type;
13441
13439
}
@@ -13448,9 +13446,20 @@ namespace ts {
13448
13446
undefined;
13449
13447
}
13450
13448
13451
- function createTemplateType(texts: readonly string[], types: readonly Type[]) {
13449
+ function applyTemplateCasing(str: string, casing: TemplateCasing) {
13450
+ switch (casing) {
13451
+ case TemplateCasing.Uppercase: return str.toUpperCase();
13452
+ case TemplateCasing.Lowercase: return str.toLowerCase();
13453
+ case TemplateCasing.Capitalize: return str.charAt(0).toUpperCase() + str.slice(1);
13454
+ case TemplateCasing.Uncapitalize: return str.charAt(0).toLowerCase() + str.slice(1);
13455
+ }
13456
+ return str;
13457
+ }
13458
+
13459
+ function createTemplateType(texts: readonly string[], casings: readonly TemplateCasing[], types: readonly Type[]) {
13452
13460
const type = <TemplateType>createType(TypeFlags.Template);
13453
13461
type.texts = texts;
13462
+ type.casings = casings;
13454
13463
type.types = types;
13455
13464
return type;
13456
13465
}
@@ -15072,7 +15081,7 @@ namespace ts {
15072
15081
return getIndexType(instantiateType((<IndexType>type).type, mapper));
15073
15082
}
15074
15083
if (flags & TypeFlags.Template) {
15075
- return getTemplateType((<TemplateType>type).texts, instantiateTypes((<TemplateType>type).types, mapper));
15084
+ return getTemplateType((<TemplateType>type).texts, (<TemplateType>type).casings, instantiateTypes((<TemplateType>type).types, mapper));
15076
15085
}
15077
15086
if (flags & TypeFlags.IndexedAccess) {
15078
15087
return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper), /*accessNode*/ undefined, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
@@ -19931,7 +19940,7 @@ namespace ts {
19931
19940
function inferToTemplateType(source: Type, target: TemplateType) {
19932
19941
if (source.flags & (TypeFlags.StringLike | TypeFlags.Index)) {
19933
19942
const matches = source.flags & TypeFlags.StringLiteral ? inferLiteralsFromTemplateType(<StringLiteralType>source, target) :
19934
- source.flags & TypeFlags.Template && arraysEqual((<TemplateType>source).texts, target.texts) ? (<TemplateType>source).types :
19943
+ source.flags & TypeFlags.Template && arraysEqual((<TemplateType>source).texts, target.texts) && arraysEqual((<TemplateType>source).casings, target.casings) ? (<TemplateType>source).types :
19935
19944
undefined;
19936
19945
const types = target.types;
19937
19946
for (let i = 0; i < types.length; i++) {
0 commit comments