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
+5 -2
View File
@@ -1802,12 +1802,15 @@ export const Service: ServiceDecorator;
// @public // @public
export interface ServiceDecorator { export interface ServiceDecorator {
(): TypeDecorator; (): TypeDecorator;
(options?: { (options: {
autoProvided: false; autoProvided: false;
}): TypeDecorator; }): TypeDecorator;
<T>(options: {
autoProvided?: true;
factory: () => T;
}): <C extends Type<unknown>>(target: C) => Type<T>;
(options?: { (options?: {
autoProvided?: true; autoProvided?: true;
factory?: () => unknown;
}): TypeDecorator; }): TypeDecorator;
} }
+12 -4
View File
@@ -30,13 +30,21 @@ export interface ServiceDecorator {
* When `autoProvided` is set to `false`, the service won't be exposed to the dependency * 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. * 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 * Creates a service that is automatically provided and uses
* `factory` allows for the runtime value to be replaced. * 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;
} }
/** /**
@@ -28,7 +28,7 @@ describe('@Service decorator', () => {
it('should be able to provide an alternate implementation using `factory`', () => { it('should be able to provide an alternate implementation using `factory`', () => {
@Service({factory: () => ({value: 'alternate'})}) @Service({factory: () => ({value: 'alternate'})})
class MyService { class MyService {
readonly value = 'MyService'; value = 'MyService';
} }
@Component({template: ''}) @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', () => { it('should be able to provide an alternate implementation using `factory` when `autoProvided` is set to true', () => {
@Service({autoProvided: true, factory: () => ({value: 'alternate'})}) @Service({autoProvided: true, factory: () => ({value: 'alternate'})})
class MyService { class MyService {
readonly value = 'MyService'; value = 'MyService';
} }
@Component({template: ''}) @Component({template: ''})
@@ -60,7 +60,7 @@ describe('@Service decorator', () => {
@Service({factory: () => ({value: inject(token)})}) @Service({factory: () => ({value: inject(token)})})
class MyService { class MyService {
readonly value = 'MyService'; value = 'MyService';
} }
@Component({template: ''}) @Component({template: ''})
@@ -153,7 +153,7 @@ describe('@Service decorator', () => {
it('should be able to override a service that has a factory', () => { it('should be able to override a service that has a factory', () => {
@Service({factory: () => ({value: 'factory'})}) @Service({factory: () => ({value: 'factory'})})
class MyService { class MyService {
readonly value = 'MyService'; value = 'MyService';
} }
@Service() @Service()