Merge pull request #22251 from jack-williams/jack-williams/no-implicit-symbol-to-string

Fix #19666: Check for symbol types in template expressions
This commit is contained in:
Mohamed Hegazy 2018-03-30 09:32:11 -07:00 committed by GitHub
commit 31c3ef51d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 201 additions and 1 deletions

View File

@ -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;

View File

@ -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'.

View File

@ -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;

View File

@ -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))

View File

@ -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

View File

@ -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);

View File

@ -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))

View File

@ -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

View File

@ -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}`;

View File

@ -0,0 +1,6 @@
// taggedTemplateStringWithSymbolExpression01.ts
declare function foo(template: any, val: symbol): number;
let x!: symbol;
let result: number = foo`${x}`;