Skip to content

Can't use nullable strings in template literal #2918

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mattjohnsonpint opened this issue May 13, 2025 · 8 comments · Fixed by #2928
Closed

Can't use nullable strings in template literal #2918

mattjohnsonpint opened this issue May 13, 2025 · 8 comments · Fixed by #2928
Assignees
Labels

Comments

@mattjohnsonpint
Copy link
Contributor

mattjohnsonpint commented May 13, 2025

Bug description

Template literal strings can interpolate most scalar value types, including strings, numbers, booleans, etc.

However, trying to use a nullable string in a template literal currently leads to a compiler error.

Steps to reproduce

const x: string | null = "abc";  
const s = `test: '${x}'`
ERROR TS2685: The 'this' types of each signature are incompatible.
     :
   2 │ const s = `test: '${x}'`
     │                     ~
     └─ in assembly/index.ts(3,23)
     :
 644 │ toString(): String {
     │ ~~~~~~~~~~~~~~~~~~
     └─ in ~lib/string.ts(644,3)

The error is confusing, as it doesn't explain why there's an incompatibility, and there's only one value the user is putting in the template literal.

AssemblyScript version

v0.27.36

@mattjohnsonpint
Copy link
Contributor Author

mattjohnsonpint commented Jun 1, 2025

How do we want this to actually behave? I can see a two options:

  • We could allow nullable types in template literals, so that ${x} would behave like ${x == null ? "" : x.toString() }

  • We could disallow nullable types in templates, but give a better error so the user knows they have to check for null themselves.

If we do allow them, we could choose to emit "", "null" or "<null>" or some other value. (This behavior seems to vary across languages.)

@CountBleck
Copy link
Member

I'd go with emitting "null" since that's what JS does.

@CountBleck CountBleck self-assigned this Jun 1, 2025
@MaxGraey
Copy link
Member

MaxGraey commented Jun 1, 2025

If string is nullable, it should be a compiler error similar for concat nullable plus non-nullable nullableStr + 'foo'. For external interop calls it's also guaranteed by binding generator and produce runtime error from js side

@CountBleck
Copy link
Member

I think this is a bit different, since template literals support interpolating numbers, arrays, and other non-string objects, so other QoL features like emitting "null" might be desirable...

@HerrCai0907
Copy link
Member

It maybe toString's issue. According to ECMAscript spec. ToString should return null for null. But in AS, we just reject this cases. @MaxGraey @CountBleck @dcodeIO WDYT? should we follow this spec?

@CountBleck
Copy link
Member

Making users have to adjust their own toString methods to accept something like this: SomeClass | null instead of this: SomeClass while also forcing them to write if (this == null) return "null" is unpleasant.

Luckily, JavaScript doesn't allow you to do null.toString(), so we don't have to change anything about toString. The spec, if I understand it correctly, is referring to implicitly coercing null to strings. The only place we do that coercion is in template literals (we don't support code like [1, 2, 3] + "hi"), so my opinion is that we should just support nullable strings in template literals, with "null" being emitted if the parameter is null.

@MaxGraey Does this make sense?

@HerrCai0907
Copy link
Member

I think a wrapper is needed when we emit toString for nullable class. It should be done by ASC instead of changing the toString method, in detail, it is in module.makeToString function.

@CountBleck
Copy link
Member

I agree, since only template literals use that function anyway. Essentially we need to emit theObject ? theObject.toString() : "null" for nullable objects in makeToString.

CountBleck added a commit to CountBleck/assemblyscript that referenced this issue Jun 3, 2025
We basically compile nullable strings down to a ternary:
`expr ? expr.toString() : "null"`

Fixes AssemblyScript#2918.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants