Skip to content

Commit

Permalink
feat: add typeof modifier in template string
Browse files Browse the repository at this point in the history
  • Loading branch information
Jack-Works committed Sep 7, 2020
1 parent 0353053 commit 198754f
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 5 deletions.
18 changes: 13 additions & 5 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13439,12 +13439,15 @@ namespace ts {
let text = texts[0];
for (let i = 0; i < types.length; i++) {
const t = types[i];
if (t.flags & TypeFlags.Literal) {
const s = applyTemplateCasing(getTemplateStringForType(t) || "", casings[i]);
const casingType = casings[i];
const isGeneric = isGenericIndexType(t);
const resolvable = (t.flags & TypeFlags.Literal) || (!isGeneric && casingType === TemplateCasing.TypeOf);
if (resolvable) {
const s = applyTemplateCasing(getTemplateStringForType(t, casingType) || "", casingType);
text += s;
text += texts[i + 1];
}
else if (isGenericIndexType(t)) {
else if (isGeneric) {
newTypes.push(t);
newCasings.push(casings[i]);
newTexts.push(text);
Expand All @@ -13466,7 +13469,10 @@ namespace ts {
return type;
}

function getTemplateStringForType(type: Type) {
function getTemplateStringForType(type: Type, casing: TemplateCasing) {
if (casing === TemplateCasing.TypeOf) {
return getTypeNameForErrorDisplay(type);
}
return type.flags & TypeFlags.StringLiteral ? (<StringLiteralType>type).value :
type.flags & TypeFlags.NumberLiteral ? "" + (<NumberLiteralType>type).value :
type.flags & TypeFlags.BigIntLiteral ? pseudoBigIntToString((<BigIntLiteralType>type).value) :
Expand Down Expand Up @@ -31424,7 +31430,9 @@ namespace ts {
getTypeFromTypeNode(node);
for (const span of node.templateSpans) {
const type = getTypeFromTypeNode(span.type);
checkTypeAssignableTo(type, templateConstraintType, span.type);
if (span.casing !== TemplateCasing.TypeOf) {
checkTypeAssignableTo(type, templateConstraintType, span.type);
}
if (!everyType(type, t => !!(t.flags & TypeFlags.Literal) || isGenericIndexType(t))) {
error(span.type, Diagnostics.Template_type_argument_0_is_not_literal_type_or_a_generic_type, typeToString(type));
}
Expand Down
1 change: 1 addition & 0 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2013,6 +2013,7 @@ namespace ts {
node.casing === TemplateCasing.Lowercase ? "lowercase" :
node.casing === TemplateCasing.Capitalize ? "capitalize" :
node.casing === TemplateCasing.Uncapitalize ? "uncapitalize" :
node.casing === TemplateCasing.TypeOf ? "typeof" :
undefined;
if (keyword) {
writeKeyword(keyword);
Expand Down
1 change: 1 addition & 0 deletions src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2621,6 +2621,7 @@ namespace ts {
parseOptional(SyntaxKind.LowercaseKeyword) ? TemplateCasing.Lowercase :
parseOptional(SyntaxKind.CapitalizeKeyword) ? TemplateCasing.Capitalize :
parseOptional(SyntaxKind.UncapitalizeKeyword) ? TemplateCasing.Uncapitalize :
parseOptional(SyntaxKind.TypeOfKeyword) ? TemplateCasing.TypeOf :
TemplateCasing.None;
}

Expand Down
1 change: 1 addition & 0 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1672,6 +1672,7 @@ namespace ts {
Lowercase,
Capitalize,
Uncapitalize,
TypeOf,
}

// Note: 'brands' in our syntax nodes serve to give us a small amount of nominal typing.
Expand Down

0 comments on commit 198754f

Please sign in to comment.