Skip to content

Conversation

@hazzard993
Copy link
Contributor

Closes #611

Raw strings are usable too.

Equivalent output code does look hard to read.

function func(strings: TemplateStringsArray, ...expressions: any[]) {}

func`\u00A9 ${4}`;
--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
function func(self, strings, ...)
end
func(_G, {
    "© ",
    "",
    raw = {
        "\\u00A9 ",
        "",
    },
}, 4)

Copy link
Collaborator

@tomblind tomblind left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a quick test and stumbled on the fact that if the tag function's first argument is not typed as TemplateStringsArray (could be any[], string[], etc...), getResolvedSignature fails and so no context parameter is passed to the function in the resulting lua. I'm not sure off the top of my head how to best handle that, but we'll need to do something or the code breaks at runtime.

@tomblind
Copy link
Collaborator

I did some more tests:

Works:

  • TemplateStringsArray
  • readonly string[]
  • ReadonlyArray<string>
  • any
  • unknown

Doesn't work:

  • string[]
  • any[]

So it seems getResolvedSignature fails if the type is a non-readonly array type.

Perhaps we should just require the type of that parameter to be TemplateStringsArray to keep things simple?

@ark120202
Copy link
Contributor

Turns out getResolvedSignature resolves the correct signature there when called from a non-diagnostic-producing type checker. It is caused by a slight difference between them: microsoft/TypeScript#28584 (comment). This difference was removed in microsoft/TypeScript#28564, but it doesn't seem like it's going to get merged any time soon. For now I don't think there's need to do anything - user would get a semantic error in this case anyway.

@tomblind
Copy link
Collaborator

tomblind commented Jun 20, 2019

I think we should do something since the result right now is bad lua being silently generated.
Nevermind. I am wrong. Ignore me 😄

@hazzard993
Copy link
Contributor Author

Is there still anything weird to fix up with the getResolvedSignature issue?

@tomblind
Copy link
Collaborator

getResolvedSignature should be fine - turns out an error is thrown by TS if the wrong type is attempted to be used, and I just wasn't seeing it when I was testing.

joinRawResult: "hello \\`",
},
{
callExpression: "obj.func`hello ${'propertyAccessExpression'}`",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it always calls functions with global context:

const obj = {
    func(strings: TemplateStringsArray, ...expressions: any[]) {
        console.log(this === obj); // `true` in JS, `false` in Lua
    },
};

obj.func`hello`;
local obj = {func = function(self, strings, ...)
    print(self == obj)
end}
obj.func(_G, { -- should be `obj`
    "hello",
    raw = {"hello"},
})

Also there is a case where obj isn't pure:

getObj()["func"]`hello`;

In call expressions it's handled like that:

(function()
    local ____TS_self = getObj(_G)
    return ____TS_self.func(____TS_self, {
        "hello",
        raw = {"hello"},
    })
end)()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good find! Took a bit to understand what to do here, I've added transformContextualCallExpression in an attempt to preserve this left hand side behaviour to call-like expressions which includes these template literals.

@Perryvw Perryvw merged commit eb7ae08 into TypeScriptToLua:master Jul 2, 2019
@hazzard993 hazzard993 deleted the tagged-template-literals branch July 2, 2019 22:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: Tagged template literals

4 participants