fix(core): enforce return type for service factory

Updates the `factory` signature in `@Service` to enforce the type of the returned value.
This commit is contained in:
Kristiyan Kostadinov 2026-05-01 10:10:41 +02:00 committed by Alex Rickabaugh
parent 71cc9e685c
commit 49748b5c79
3 changed files with 21 additions and 10 deletions

View file

@ -1802,12 +1802,15 @@ export const Service: ServiceDecorator;
// @public
export interface ServiceDecorator {
(): TypeDecorator;
(options?: {
(options: {
autoProvided: false;
}): TypeDecorator;
<T>(options: {
autoProvided?: true;
factory: () => T;
}): <C extends Type<unknown>>(target: C) => Type<T>;
(options?: {
autoProvided?: true;
factory?: () => unknown;
}): TypeDecorator;
}

View file

@ -30,13 +30,21 @@ export interface ServiceDecorator {
* When `autoProvided` is set to `false`, the service won't be exposed to the dependency
* injection system automatically. It is up to the user to expose it in a providers list.
*/
(options?: {autoProvided: false}): TypeDecorator;
(options: {autoProvided: false}): TypeDecorator;
/**
* Creates a service that is automatically provided. Passing an optional
* `factory` allows for the runtime value to be replaced.
* Creates a service that is automatically provided and uses
* the value returned from the `factory` function.
*/
(options?: {autoProvided?: true; factory?: () => unknown}): TypeDecorator;
<T>(options: {
autoProvided?: true;
factory: () => T;
}): <C extends Type<unknown>>(target: C) => Type<T>;
/**
* Creates a service that is automatically provided.
*/
(options?: {autoProvided?: true}): TypeDecorator;
}
/**

View file

@ -28,7 +28,7 @@ describe('@Service decorator', () => {
it('should be able to provide an alternate implementation using `factory`', () => {
@Service({factory: () => ({value: 'alternate'})})
class MyService {
readonly value = 'MyService';
value = 'MyService';
}
@Component({template: ''})
@ -43,7 +43,7 @@ describe('@Service decorator', () => {
it('should be able to provide an alternate implementation using `factory` when `autoProvided` is set to true', () => {
@Service({autoProvided: true, factory: () => ({value: 'alternate'})})
class MyService {
readonly value = 'MyService';
value = 'MyService';
}
@Component({template: ''})
@ -60,7 +60,7 @@ describe('@Service decorator', () => {
@Service({factory: () => ({value: inject(token)})})
class MyService {
readonly value = 'MyService';
value = 'MyService';
}
@Component({template: ''})
@ -153,7 +153,7 @@ describe('@Service decorator', () => {
it('should be able to override a service that has a factory', () => {
@Service({factory: () => ({value: 'factory'})})
class MyService {
readonly value = 'MyService';
value = 'MyService';
}
@Service()