Skip to content
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

[BUGFIX BETA] Make the *type* for SafeString public #20373

Merged
merged 1 commit into from
Feb 14, 2023

Conversation

chriskrycho
Copy link
Contributor

This type has been effectively "intimate" for many years, and fits in the same bucket as e.g. Transition: it is not user-constructible, but will be constructed by the framework and users need to be able to name it. For example, ember-intl needs to be able to see that a string has been marked as trusted to do the right thing to emit it.

Internally, clean up a few long-standing TS issues (any etc.), make SafeString explicitly implement the contract from Glimmer so that if that contract changes, we will know at the definition site, and make the implementation details of how SafeString handles the string it wraps private. (This does not use a #-private field because private class fields have some non-trivial overhead in transpiled contexts, and SafeString can appear in fairly hot rendering paths.)


I will back port this to the preview types as well once we merge this.

@chriskrycho chriskrycho added Bug TypeScript Work on Ember’s types labels Feb 14, 2023
@chriskrycho chriskrycho changed the title Make the type for SafeString public [BUGFIX BETA] Make the type for SafeString public Feb 14, 2023
This type has been effectively "intimate" for many years, and fits in
the same bucket as e.g. `Transition`: it is not user-constructible, but
will be constructed by the framework and users need to be able to name
it. For example, `ember-intl` needs to be able to see that a string has
been marked as trusted to do the right thing to emit it.

Internally, clean up a few long-standing TS issues (`any` etc.), make
`SafeString` explicitly implement the contract from Glimmer so that if
that contract changes, we will know at the definition site, and make
the implementation details of how `SafeString` handles the string it
wraps `private`. (This does not use a `#`-private field because private
class fields have some non-trivial overhead in transpiled contexts, and
`SafeString` can appear in fairly hot rendering paths.)
@chriskrycho chriskrycho merged commit 22b3879 into master Feb 14, 2023
@chriskrycho chriskrycho deleted the just-SafeString branch February 14, 2023 23:36
@chriskrycho chriskrycho changed the title [BUGFIX BETA] Make the type for SafeString public [BUGFIX LTS] Make the type for SafeString public Feb 14, 2023
@chriskrycho chriskrycho restored the just-SafeString branch February 14, 2023 23:39
@chriskrycho chriskrycho changed the title [BUGFIX LTS] Make the type for SafeString public [BUGFIX BETA] Make the *type* for SafeString public Feb 14, 2023
public string: string;
import type { SafeString as GlimmerSafeString } from '@glimmer/runtime';

export class SafeString implements GlimmerSafeString {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I realized after landing this: we'll need docs here to make it show up appropriately. I'll follow up to that effect tomorrow.

@jrjohnson
Copy link
Sponsor

I'm not sure where this falls on the 'is a bug / is a mistake in our code' spectrum, but we were accessing the results of htmlSafe(str).string in tests and now need to change these to htmlSafe(str).toString() after this change. It's fairly straightforward to fix, but I'm surprised the string property which was maybe sort of public got killed in a minor version update.

@chriskrycho
Copy link
Contributor Author

The class itself was not public, so relying on any part of it was subject to breakage at any time. The field was only public for internal use. When making the class public, I chose to hide that part of the implementation so that if we evolve this in the future we can do so without breaking the contract. In the future, don’t rely on private API, and you won’t get broken when it changes!

@jrjohnson
Copy link
Sponsor

I hear that, and honestly this is no big deal, but I wasn't relying on anything like a type when we wrote this code 8 years ago 😁, what we were using was the result of htmlSafe() and I'm guessing it was a POJO or possible some object that we could discover has a string property on it in a debugger. It was an easy fix, I just wanted to add a comment here for the next sluther and hopefully make it a bit more SEO for someone else looking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug TypeScript Work on Ember’s types
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants