-
-
Notifications
You must be signed in to change notification settings - Fork 2k
Description
Which @ngrx/* package(s) are relevant/related to the feature request?
eslint-plugin
Information
For certain APIs, users need to use the type
function to define a type.
Common areas are in signalStoreFeature
when defining constraints
for the input or in the Events plugin.
However, it’s easy to forget to call type
, which can
lead to subtle and confusing type issues.
INVALID
const loadEvent = event('Load', type<number>); // ⚠️invalid
const bookEvents = eventGroup({
source: 'Book',
events: {
load: type<number>, // ⚠️ invalid
},
});
In both examples above, if type<number>
is not called (i.e., written as
type<number>()
), the resulting type of loadEvent
or bookEvents.load
will
incorrectly be inferred as () => number
.
VALID
const loadEvent = event('Load', type<number>()); // ✅ valid
const bookEvents = eventGroup({
source: 'Book',
events: {
load: type<number>(), // ✅ valid
},
});
We find another common use case in the signalStoreFeature
:
INVALID
export function withBaz() {
return signalStoreFeature(
{
props: type<{ foo: Signal<string> }> // ⚠️ invalid
},
// ...
);
}
VALID
export function withBaz() {
return signalStoreFeature(
{
props: type<{ foo: Signal<string> }> () // ✅ valid
},
// ...
);
}
To prevent such mistakes, an ESLint rule should be introduced that verifies
type
is always called.
The ESLint rule should also be able to detect an alias of type
, like:
INVALID
import { type as defineType } from '@ngrx/signal';
export function withBaz() {
return signalStoreFeature(
{
props: defineType<{ foo: Signal<string> }> // ⚠️ invalid
},
// ...
);
}
VALID
import { type as defineType } from '@ngrx/signal';
export function withBaz() {
return signalStoreFeature(
{
props: defineType<{ foo: Signal<string> }()> // ✅ valid
},
// ...
);
}
Describe any alternatives/workarounds you're currently using
No response
I would be willing to submit a PR to fix this issue
- Yes
- No