diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5d8b10eb3da..c0b96f2d986 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19684,7 +19684,9 @@ namespace ts { // A place where we actually *are* concerned with the expressions' types are // in tagged templates. forEach(node.templateSpans, templateSpan => { - checkExpression(templateSpan.expression); + if (maybeTypeOfKind(checkExpression(templateSpan.expression), TypeFlags.ESSymbolLike)) { + error(templateSpan.expression, Diagnostics.Type_0_cannot_be_converted_to_type_1, typeToString(esSymbolType), typeToString(stringType)); + } }); return stringType; diff --git a/tests/baselines/reference/noImplicitSymbolToString.errors.txt b/tests/baselines/reference/noImplicitSymbolToString.errors.txt new file mode 100644 index 00000000000..6dae5c5d76f --- /dev/null +++ b/tests/baselines/reference/noImplicitSymbolToString.errors.txt @@ -0,0 +1,32 @@ +tests/cases/compiler/noImplicitSymbolToString.ts(6,30): error TS2352: Type 'symbol' cannot be converted to type 'string'. +tests/cases/compiler/noImplicitSymbolToString.ts(7,30): error TS2469: The '+' operator cannot be applied to type 'symbol'. +tests/cases/compiler/noImplicitSymbolToString.ts(8,8): error TS2469: The '+=' operator cannot be applied to type 'symbol'. +tests/cases/compiler/noImplicitSymbolToString.ts(13,47): error TS2352: Type 'symbol' cannot be converted to type 'string'. +tests/cases/compiler/noImplicitSymbolToString.ts(13,90): error TS2352: Type 'symbol' cannot be converted to type 'string'. + + +==== tests/cases/compiler/noImplicitSymbolToString.ts (5 errors) ==== + // Fix #19666 + + let symbol!: symbol; + let str = "hello "; + + const templateStr = `hello ${symbol}`; + ~~~~~~ +!!! error TS2352: Type 'symbol' cannot be converted to type 'string'. + const appendStr = "hello " + symbol; + ~~~~~~ +!!! error TS2469: The '+' operator cannot be applied to type 'symbol'. + str += symbol; + ~~~~~~ +!!! error TS2469: The '+=' operator cannot be applied to type 'symbol'. + + let symbolUnionNumber!: symbol | number; + let symbolUnionString!: symbol | string; + + const templateStrUnion = `union with number ${symbolUnionNumber} and union with string ${symbolUnionString}`; + ~~~~~~~~~~~~~~~~~ +!!! error TS2352: Type 'symbol' cannot be converted to type 'string'. + ~~~~~~~~~~~~~~~~~ +!!! error TS2352: Type 'symbol' cannot be converted to type 'string'. + \ No newline at end of file diff --git a/tests/baselines/reference/noImplicitSymbolToString.js b/tests/baselines/reference/noImplicitSymbolToString.js new file mode 100644 index 00000000000..836d5abe8a9 --- /dev/null +++ b/tests/baselines/reference/noImplicitSymbolToString.js @@ -0,0 +1,26 @@ +//// [noImplicitSymbolToString.ts] +// Fix #19666 + +let symbol!: symbol; +let str = "hello "; + +const templateStr = `hello ${symbol}`; +const appendStr = "hello " + symbol; +str += symbol; + +let symbolUnionNumber!: symbol | number; +let symbolUnionString!: symbol | string; + +const templateStrUnion = `union with number ${symbolUnionNumber} and union with string ${symbolUnionString}`; + + +//// [noImplicitSymbolToString.js] +// Fix #19666 +var symbol; +var str = "hello "; +var templateStr = "hello " + symbol; +var appendStr = "hello " + symbol; +str += symbol; +var symbolUnionNumber; +var symbolUnionString; +var templateStrUnion = "union with number " + symbolUnionNumber + " and union with string " + symbolUnionString; diff --git a/tests/baselines/reference/noImplicitSymbolToString.symbols b/tests/baselines/reference/noImplicitSymbolToString.symbols new file mode 100644 index 00000000000..b2a08e151ab --- /dev/null +++ b/tests/baselines/reference/noImplicitSymbolToString.symbols @@ -0,0 +1,32 @@ +=== tests/cases/compiler/noImplicitSymbolToString.ts === +// Fix #19666 + +let symbol!: symbol; +>symbol : Symbol(symbol, Decl(noImplicitSymbolToString.ts, 2, 3)) + +let str = "hello "; +>str : Symbol(str, Decl(noImplicitSymbolToString.ts, 3, 3)) + +const templateStr = `hello ${symbol}`; +>templateStr : Symbol(templateStr, Decl(noImplicitSymbolToString.ts, 5, 5)) +>symbol : Symbol(symbol, Decl(noImplicitSymbolToString.ts, 2, 3)) + +const appendStr = "hello " + symbol; +>appendStr : Symbol(appendStr, Decl(noImplicitSymbolToString.ts, 6, 5)) +>symbol : Symbol(symbol, Decl(noImplicitSymbolToString.ts, 2, 3)) + +str += symbol; +>str : Symbol(str, Decl(noImplicitSymbolToString.ts, 3, 3)) +>symbol : Symbol(symbol, Decl(noImplicitSymbolToString.ts, 2, 3)) + +let symbolUnionNumber!: symbol | number; +>symbolUnionNumber : Symbol(symbolUnionNumber, Decl(noImplicitSymbolToString.ts, 9, 3)) + +let symbolUnionString!: symbol | string; +>symbolUnionString : Symbol(symbolUnionString, Decl(noImplicitSymbolToString.ts, 10, 3)) + +const templateStrUnion = `union with number ${symbolUnionNumber} and union with string ${symbolUnionString}`; +>templateStrUnion : Symbol(templateStrUnion, Decl(noImplicitSymbolToString.ts, 12, 5)) +>symbolUnionNumber : Symbol(symbolUnionNumber, Decl(noImplicitSymbolToString.ts, 9, 3)) +>symbolUnionString : Symbol(symbolUnionString, Decl(noImplicitSymbolToString.ts, 10, 3)) + diff --git a/tests/baselines/reference/noImplicitSymbolToString.types b/tests/baselines/reference/noImplicitSymbolToString.types new file mode 100644 index 00000000000..c21c0e07bfd --- /dev/null +++ b/tests/baselines/reference/noImplicitSymbolToString.types @@ -0,0 +1,38 @@ +=== tests/cases/compiler/noImplicitSymbolToString.ts === +// Fix #19666 + +let symbol!: symbol; +>symbol : symbol + +let str = "hello "; +>str : string +>"hello " : "hello " + +const templateStr = `hello ${symbol}`; +>templateStr : string +>`hello ${symbol}` : string +>symbol : symbol + +const appendStr = "hello " + symbol; +>appendStr : string +>"hello " + symbol : string +>"hello " : "hello " +>symbol : symbol + +str += symbol; +>str += symbol : string +>str : string +>symbol : symbol + +let symbolUnionNumber!: symbol | number; +>symbolUnionNumber : number | symbol + +let symbolUnionString!: symbol | string; +>symbolUnionString : string | symbol + +const templateStrUnion = `union with number ${symbolUnionNumber} and union with string ${symbolUnionString}`; +>templateStrUnion : string +>`union with number ${symbolUnionNumber} and union with string ${symbolUnionString}` : string +>symbolUnionNumber : number | symbol +>symbolUnionString : string | symbol + diff --git a/tests/baselines/reference/taggedTemplateStringWithSymbolExpression01.js b/tests/baselines/reference/taggedTemplateStringWithSymbolExpression01.js new file mode 100644 index 00000000000..4f02e7644f7 --- /dev/null +++ b/tests/baselines/reference/taggedTemplateStringWithSymbolExpression01.js @@ -0,0 +1,17 @@ +//// [taggedTemplateStringWithSymbolExpression01.ts] +// taggedTemplateStringWithSymbolExpression01.ts + +declare function foo(template: any, val: symbol): number; +let x!: symbol; + +let result: number = foo`${x}`; + + +//// [taggedTemplateStringWithSymbolExpression01.js] +// taggedTemplateStringWithSymbolExpression01.ts +var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) { + if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } + return cooked; +}; +var x; +var result = foo(__makeTemplateObject(["", ""], ["", ""]), x); diff --git a/tests/baselines/reference/taggedTemplateStringWithSymbolExpression01.symbols b/tests/baselines/reference/taggedTemplateStringWithSymbolExpression01.symbols new file mode 100644 index 00000000000..743d31193d4 --- /dev/null +++ b/tests/baselines/reference/taggedTemplateStringWithSymbolExpression01.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/taggedTemplateStringWithSymbolExpression01.ts === +// taggedTemplateStringWithSymbolExpression01.ts + +declare function foo(template: any, val: symbol): number; +>foo : Symbol(foo, Decl(taggedTemplateStringWithSymbolExpression01.ts, 0, 0)) +>template : Symbol(template, Decl(taggedTemplateStringWithSymbolExpression01.ts, 2, 21)) +>val : Symbol(val, Decl(taggedTemplateStringWithSymbolExpression01.ts, 2, 35)) + +let x!: symbol; +>x : Symbol(x, Decl(taggedTemplateStringWithSymbolExpression01.ts, 3, 3)) + +let result: number = foo`${x}`; +>result : Symbol(result, Decl(taggedTemplateStringWithSymbolExpression01.ts, 5, 3)) +>foo : Symbol(foo, Decl(taggedTemplateStringWithSymbolExpression01.ts, 0, 0)) +>x : Symbol(x, Decl(taggedTemplateStringWithSymbolExpression01.ts, 3, 3)) + diff --git a/tests/baselines/reference/taggedTemplateStringWithSymbolExpression01.types b/tests/baselines/reference/taggedTemplateStringWithSymbolExpression01.types new file mode 100644 index 00000000000..f1a16a7f8ef --- /dev/null +++ b/tests/baselines/reference/taggedTemplateStringWithSymbolExpression01.types @@ -0,0 +1,18 @@ +=== tests/cases/compiler/taggedTemplateStringWithSymbolExpression01.ts === +// taggedTemplateStringWithSymbolExpression01.ts + +declare function foo(template: any, val: symbol): number; +>foo : (template: any, val: symbol) => number +>template : any +>val : symbol + +let x!: symbol; +>x : symbol + +let result: number = foo`${x}`; +>result : number +>foo`${x}` : number +>foo : (template: any, val: symbol) => number +>`${x}` : string +>x : symbol + diff --git a/tests/cases/compiler/noImplicitSymbolToString.ts b/tests/cases/compiler/noImplicitSymbolToString.ts new file mode 100644 index 00000000000..16690d6d845 --- /dev/null +++ b/tests/cases/compiler/noImplicitSymbolToString.ts @@ -0,0 +1,13 @@ +// Fix #19666 + +let symbol!: symbol; +let str = "hello "; + +const templateStr = `hello ${symbol}`; +const appendStr = "hello " + symbol; +str += symbol; + +let symbolUnionNumber!: symbol | number; +let symbolUnionString!: symbol | string; + +const templateStrUnion = `union with number ${symbolUnionNumber} and union with string ${symbolUnionString}`; diff --git a/tests/cases/compiler/taggedTemplateStringWithSymbolExpression01.ts b/tests/cases/compiler/taggedTemplateStringWithSymbolExpression01.ts new file mode 100644 index 00000000000..0cbf3c00e38 --- /dev/null +++ b/tests/cases/compiler/taggedTemplateStringWithSymbolExpression01.ts @@ -0,0 +1,6 @@ +// taggedTemplateStringWithSymbolExpression01.ts + +declare function foo(template: any, val: symbol): number; +let x!: symbol; + +let result: number = foo`${x}`;