Skip to content

Commit c05e104

Browse files
devversionthePunderWoman
authored andcommitted
refactor(core): introduce output() signature and runtime code (angular#54217)
This commit introduces the `output()` function and corresponding runtime code. In practice, `output()` will defer to `EventEmitter` as outlined in the RFC, but we are considering limiting the type to a minimal version that is not coupled with RxJS, less complex, and also has better type safety around emitting of values. E.g. currently `EventEmitter.emit` can always be called without any value, even though the output may be typed to always pass around values of type `T`. This could cause subtle and confusing bugs. PR Close angular#54217
1 parent f7da77b commit c05e104

File tree

4 files changed

+69
-1
lines changed

4 files changed

+69
-1
lines changed

packages/core/src/authoring.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@
1212
export {InputFunction} from './authoring/input/input';
1313
export {InputOptions, InputOptionsWithoutTransform, InputOptionsWithTransform, InputSignal, InputSignalWithTransform, ɵINPUT_SIGNAL_BRAND_WRITE_TYPE} from './authoring/input/input_signal';
1414
export {ɵUnwrapDirectiveSignalInputs} from './authoring/input/input_type_checking';
15+
export {output as ɵoutput, OutputEmitter as ɵOutputEmitter, OutputOptions as ɵOutputOptions} from './authoring/output';

packages/core/src/authoring/output.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {EventEmitter} from '../event_emitter';
10+
11+
/**
12+
* An `OutputEmitter` is created by the `output()` function and can be
13+
* used to emit values to consumers of your directive or component.
14+
*
15+
* Consumers of your directive/component can bind to the output and
16+
* subscribe to changes via the bound event syntax. For example:
17+
*
18+
* ```html
19+
* <my-comp (valueChange)="processNewValue($event)" />
20+
* ```
21+
*
22+
* @developerPreview
23+
*/
24+
export interface OutputEmitter<T> {
25+
emit(value: T): void;
26+
27+
// TODO: Consider exposing `subscribe` for dynamically created components.
28+
/** @internal */
29+
subscribe(listener: (v: T) => void): void;
30+
}
31+
32+
/**
33+
* Options for declaring an output.
34+
*
35+
* @developerPreview
36+
*/
37+
export interface OutputOptions {
38+
alias?: string;
39+
}
40+
41+
/**
42+
* The `outputs` function allows declaration of outputs in directives and
43+
* components.
44+
*
45+
* Initializes an output that can emit values to consumers of your
46+
* directive/component.
47+
*
48+
* @usageNotes
49+
* Initialize an output in your directive by declaring a
50+
* class field and initializing it with the `output()` function.
51+
*
52+
* ```ts
53+
* @Directive({..})
54+
* export class MyDir {
55+
* nameChange = output<string>(); // OutputEmitter<string>
56+
* onClick = output(); // OutputEmitter<void>
57+
* }
58+
* ```
59+
*
60+
* @developerPreview
61+
*/
62+
export function output<T = void>(opts?: OutputOptions): OutputEmitter<T> {
63+
return new EventEmitter();
64+
}

packages/core/test/bundling/defer/bundle.golden_symbols.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1640,6 +1640,9 @@
16401640
{
16411641
"name": "init_operators"
16421642
},
1643+
{
1644+
"name": "init_output"
1645+
},
16431646
{
16441647
"name": "init_partial"
16451648
},

packages/core/test/bundling/router/bundle.golden_symbols.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1980,7 +1980,7 @@
19801980
"name": "tap"
19811981
},
19821982
{
1983-
"name": "throwError2"
1983+
"name": "throwError"
19841984
},
19851985
{
19861986
"name": "throwIfEmpty"

0 commit comments

Comments
 (0)