NgRX 14.3.0中createAction props泛型使用报错求解决方案
解决NgRx 14.3.0中泛型Action创建函数的编译错误
问题背景
使用@ngrx/store 14.3.0版本,想要编写一个可根据传入参数动态创建Action的泛型函数,但现有过时方案无法解决编译问题。
初始实现与编译错误
尝试编写如下泛型函数:
import { createAction, props } from '@ngrx/store'; export function loadContent<TParams extends object>(key: string) { return createAction( `[${key}] Load ${key}`, props<TParams>() ); }
出现以下编译错误:
Error: libs/state/content-primitives/src/lib/content-actions.ts:7:9 - error TS2769: No overload matches this call. Overload 1 of 3, '(type: `[${string}] Load ${string}`, config: ActionCreatorProps<TParams> & NotAllowedCheck<TParams>): ActionCreator<`[${string}] Load ${string}`, (props: TParams & NotAllowedCheck<...>) => TParams & TypedAction<...>>', gave the following error. Argument of type 'ActionCreatorProps<TParams>' is not assignable to parameter of type 'ActionCreatorProps<TParams> & NotAllowedCheck<TParams>'. Type 'ActionCreatorProps<TParams>' is not assignable to type 'NotAllowedCheck<TParams>'. Overload 2 of 3, '(type: `[${string}] Load ${string}`, creator: Creator<any[], never>): FunctionWithParametersType<any[], object & TypedAction<`[${string}] Load ${string}`>> & TypedAction<...>', gave the following error. Argument of type 'ActionCreatorProps<TParams>' is not assignable to parameter of type 'Creator<any[], never>'. Type 'ActionCreatorProps<TParams>' provides no match for the signature '(...args: any[]): never'. 7 props<TParams>() ~~~~~~~~~~~~~~~ Error: libs/state/content-primitives/src/lib/content-actions.ts:7:15 - error TS2344: Type 'TParams' does not satisfy the constraint 'NotAllowedInPropsCheck<TParams>'. Type 'object' is not assignable to type 'NotAllowedInPropsCheck<TParams>'. 7 props<TParams>() ~~~~~~~
尝试照搬源码后的问题
尝试照搬NgRx源码中props的泛型定义,修改代码如下:
import { createAction, props } from '@ngrx/store'; import { NotAllowedInPropsCheck } from '@ngrx/store/src/models'; export function loadContent<TParams extends SafeProps, SafeProps = NotAllowedInPropsCheck<TParams>>(key: string) { return createAction( `[${key}] Load ${key}`, props<TParams>() ); }
仍然无法通过编译,错误信息如下:
Error: libs/state/content-primitives/src/lib/content-actions.ts:7:9 - error TS2769: No overload matches this call. Overload 1 of 3, '(type: `[${string}] Load ${string}`, config: ActionCreatorProps<object> & "action creator cannot return an empty object"): ActionCreator<`[${string}] Load ${string}`, (props: never) => object & TypedAction<...>>', gave the following error. Argument of type 'ActionCreatorProps<TParams>' is not assignable to parameter of type 'ActionCreatorProps<object> & "action creator cannot return an empty object"'. Type 'ActionCreatorProps<TParams>' is not assignable to type 'ActionCreatorProps<object>'. Type 'TParams' is not assignable to type 'object'. Type 'SafeProps' is not assignable to type 'object'. Overload 2 of 3, '(type: `[${string}] Load ${string}`, creator: Creator<any[], never>): FunctionWithParametersType<any[], object & TypedAction<`[${string}] Load ${string}`>> & TypedAction<...>', gave the following error. Argument of type 'ActionCreatorProps<TParams>' is not assignable to parameter of type 'Creator<any[], never>'. Type 'ActionCreatorProps<TParams>' provides no match for the signature '(...args: any[]): never'. 7 props<TParams>() ~~~~~~~~~~~~~~~ libs/state/content-primitives/src/lib/content-actions.ts:4:56 4 export function loadContent<TParams extends SafeProps, SafeProps = NotAllowedInPropsCheck<TParams>>(key: string) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This type parameter might need an `extends object` constraint. Error: libs/state/content-primitives/src/lib/content-actions.ts:7:15 - error TS2344: Type 'TParams' does not satisfy the constraint 'NotAllowedInPropsCheck<TParams>'. Type 'SafeProps' is not assignable to type 'NotAllowedInPropsCheck<TParams>'. 7 props<TParams>() ~~~~~~~ libs/state/content-primitives/src/lib/content-actions.ts:4:56 4 export function loadContent<TParams extends SafeProps, SafeProps = NotAllowedInPropsCheck<TParams>>(key: string) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This type parameter might need an `extends NotAllowedInPropsCheck<TParams>` constraint.
正确解决方案
问题出在泛型约束的定义上,需要让TParams同时满足object和NotAllowedInPropsCheck<TParams>的约束(后者用于排除Action中不允许出现的属性,比如type)。修改后的代码如下:
import { createAction, props } from '@ngrx/store'; import { NotAllowedInPropsCheck } from '@ngrx/store/src/models'; export function loadContent<TParams extends object & NotAllowedInPropsCheck<TParams>>(key: string) { return createAction( `[${key}] Load ${key}`, props<TParams>() ); }
这样既保证了TParams是对象类型,又符合NgRx对Props的类型限制,编译可以正常通过,同时不需要使用any类型。
内容的提问来源于stack exchange,提问作者Bora
相关产品推荐
相关产品推荐

