microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.69k stars 12.44k forks source link

No error when templates are tagged by anything with only construct signatures #10454

Closed BobFrankston closed 8 years ago

BobFrankston commented 8 years ago

TypeScript Version: 1.8.36.0

Want to use function htmlEscape(literals, ...placeholders) {...}

but type HTMLElement${xyz} (thanks to intellisense)

This should be reported as an error since the tag function is not valid. I often run into this because intellisense doesn't know better and offers up the HTMLElement isntead.

DanielRosenwasser commented 8 years ago

Thanks for filing!

Repros:

class CtorTag { }

CtorTag `Hello world!`;
interface I {
    new (...args: any[]): string;
    new (): number;
}
var tag: I;
tag `Hello world!`;
DanielRosenwasser commented 8 years ago

Found the bug! Spec says:

If FuncExpr is of type Any, or of an object type that has no call or construct signatures but is a subtype of the Function interface, the call is an untyped function call.

The same intention was done for template tags, however, we only check whether the tag has call signatures - we don't check for construct signatures. Would you be interested in taking a swing at fixing the bug? It's an easy fix, but it's in our call resolution logic which is not the easiest to grok. No pressure of course.

BobFrankston commented 8 years ago

Would like to try but plate full and too much getting up to speed on the tools and environment. Glad it's easy ... modulo grokking.

BTW, if you speak to the C# people it would be great to get the tag feature into the language - a counterpart to Linq..

BobFrankston commented 8 years ago

I tried replacing the ... function with

'function htmlEscape(literals) { var placeholders = []; for (var _i = 1; _i < arguments.length; _i++) { placeholders[_i - 1] = arguments[_i]; } ...'

but this it gave me a mismatch error.

BobFrankston commented 8 years ago

While I'm on the subject I'll throw in a suggestion here because it is related and takes some mulling. It would great to extend the type mechanism to support tagged strings sort like an enumeration. Thus I can say that an htmlEscape doesn't just tag the string but returns an "htmlString". Similarly for SQL. Would be very much in the spirit of TypeScript as a conversation with the IDE.