Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@
"@babel/register": "^7.27.1",
"@biomejs/biome": "^2.1.2",
"@types/node": "^18.19.87",
"@types/trusted-types": "^2.0.7",
"@vitest/browser": "^3.2.4",
"@vitest/coverage-v8": "^3.2.4",
"babel-plugin-transform-rename-properties": "0.1.0",
Expand Down
2 changes: 2 additions & 0 deletions src/dom.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import { ClassAttributes, PreactDOMAttributes } from 'preact';

export interface TrustedHTML {}

// Implementations of some DOM events that are not available in TS 5.1
interface ToggleEvent extends Event {
readonly newState: string;
Expand Down
2 changes: 1 addition & 1 deletion src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export interface ClassAttributes<T> extends Attributes {
export interface PreactDOMAttributes {
children?: ComponentChildren;
dangerouslySetInnerHTML?: {
__html: string;
__html: string | TrustedHTML;

@rschristian rschristian Aug 25, 2025

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Packages listed in devDependencies won't be available at runtime, and we won't be adding deps for the sake of types. Can you vendor this type by chance?

Edit: Does this just define a .toString() that gets called? I might prefer users calling that manually & passing the result in rather than the TrustedHTML object as it'll simplify the types situation.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Trusted Types are browser DOM API so they will be available at runtime, and one of the few ways they will get it is something like DOMPurify which also uses same @types/trusted-types (which is planned to be integrated into Typescript's lib.dom.ts anyway).

Calling .toString() manually won't work because we need object to be Trusted Type at runtime on sites that are marked as Content-Security-Policy: trusted-types

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I can fake TrustedHTML like React does here, but i don't know where would that go in Preact

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Trusted Types are available at runtime, the TrustedHTML type, which you used above, will not be. That'll be a type error for every single consumer that doesn't happen to have @types/trusted-types installed at the moment, which I imagine is most.

which is planned to be integrated into Typescript's lib.dom.ts anyway

Our TS support is locked at v5.1 for the upcoming Preact 11 release line so we can't rely on this eventually making its way into lib.dom.ts. This will have to be vendored.

Calling .toString() manually won't work because we need object to be Trusted Type at runtime on sites that are marked as Content-Security-Policy: trusted-types

Gotcha, didn't realize that. Thanks!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I can fake TrustedHTML like React does here, but i don't know where would that go in Preact

We have some vendored implementations here:

// Implementations of some DOM events that are not available in TS 5.1

Before or after, either works.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I added empty TrustedHTML interface, will this work?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

An empty interface that isn't imported, so I doubt it? Is the result of DOMPurify assignable to that? It seems like it wouldn't be.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I was looking into ways to make it work, but this has gone way beyond my Typescript skills.

The simpler/lazier solution would be to simply wait until it gets merged into lib.dom.ts and Preact adopts that version.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No worries, and thanks for trying! I'll take a look when I can, maybe I can come up with a hack.

wait until it gets merged into lib.dom.ts and Preact adopts that version.

Unfortunately the minimum supported TS version should only change in a major version, and we've spent almost 6 years on v10... whilst I can't say I know what the future holds, we probably want to find a solution besides telling users to wait for v12 as that might be years away.

};
}

Expand Down