Add typing for NgElement Outputs
- Dominant language
- TypeScript
- Stars
- 101k
- Forks
- 27.5k
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 288
Description
### Which @angular/* package(s) are relevant/related to the feature request?
elements
### Description
I was experimenting with Angular's custom elements. The [documentation](https://angular.io/guide/elements) mentions how attributes/inputs of such elements could be typed,
```typescript
declare global {
interface HTMLElementTagNameMap {
'my-dialog': NgElement & WithProperties<{content: string}>;
'my-other-element': NgElement & WithProperties<{foo: 'bar'}>;
…
}
}
```
but it does not mention how the events/outputs could be typed.
### Proposed solution
I would propose to either add (similar to the WithProperties) a WithEvents/WithOutputs type or even better to add a wrapper type that does the merging of addEventListener signatures better:
Using the `type-fest` library my solution is
```typescript
import { Merge, UnionToIntersection } from "type-fest";
import { NgElement, WithProperties } from "@angular/elements";
export type TypedNgElement, Outputs extends Record = {}> = Merge<
NgElement,
WithProperties &
UnionToIntersection<
{
[K in keyof Outputs]: {
addEventListener(type: K, listener: (event: CustomEvent) => void, options?: boolean | AddEventListenerOptions): void;
};
}[keyof Outputs]
>
>;
```
That can later be used as follows:
```typescript
declare global {
interface HTMLElementTagNameMap {
"my-custom-element-selector": TypedNgElement<
{
inputOne: SomeType;
inputTwo?: boolean;
},
{
outputOne: SomeType;
outputTwo: void;
}
>;
}
}
```
### Alternatives considered
I see alternatives (as I mentioned in the solution) in the way the type is introduced.
Contributor guide
Research direction
Start by reading the @angular/elements package and the existing NgElement and WithProperties types, then review the custom elements documentation example. Compare the proposed WithEvents, WithOutputs, and wrapper-type approaches, and identify the typing behavior that should be covered. Done means an agreed public API can type custom-element output events without weakening existing input typing.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100