NGRX 减速器不会抛出不正确的分配错误

NGRX reducer does not throw incorrect assignment error

我是第一次使用 ngrx。通常在 Typescript 中,我会收到以下代码的错误分配错误,因为接口声明中未指定 other

interface IExample {
  count: number;
}

let initialState: IExample = { count: 0, other: '??????' };

// Type '{ count: number; other: string; }' is not assignable to type 'IExample'.
//   Object literal may only specify known properties, and 'other' does not exist in type 'IExample'.

但是当我创建一个 reducer 时 on 关联器 (我认为这叫做关联器) 不会抛出这个异常并且映射 other到 return 对象上。

interface IExample{
  count: number;
}

let initialState: IExample = { count: 0 };

const reducer = createReducer(
  initialState,
  on(add, (state, { payload }) => ({ 
    ...state,
    other: '??????' 
  })),
);

这是on签名:

on<State, Creators extends readonly ActionCreator[]>(...args: [any, Creators, any, OnReducer<State extends infer S ? S : never, Creators>]): ReducerTypes<State, Creators>

如何防止这些类型的错误/如何让这些编译错误按应有的方式再次显示?

注:"@ngrx/store": "^12.3.0",

如果你查看 reducer on 函数,你会发现它没有指定 return 类型。并且 Typsecript 可能无法自行确定它。您可以手动指定它,这应该强调错误:

interface IExample{
  count: number;
}

let initialState: IExample = { count: 0 };

const reducer = createReducer(
  initialState,
  on(add, (state, { payload }): IExample => ({ 
    ...state,
    other: '??????' //should be underlined now
  })),
);

但不幸的是,您必须为每个 on 函数执行此操作。希望这将在 NgRx 方面得到解决。但是在玩这个的时候我发现了其他允许你绕过 Typescript 检查的情况,Object.assign 就是其中之一。

const wrongIExample: IExample = Object.assign(initialState, { another: '????'});
// this is possible and does not throws error

只是为了说明 Typescript 仍然有其局限性这一事实。

这是一个已知问题,很遗憾,这需要在 TypeScript 中修复。 作为解决方法,您必须为 on 方法提供 return 类型。

const reducer = createReducer(
  initialState,
  on(add, (state, { payload }): IExample => ({ 
    ...state,
    other: '??????' 
    ~~~~~~ error
  })),
);

因为这是一个常见问题,所以它有自己的 lint 规则 https://github.com/timdeschryver/eslint-plugin-ngrx/blob/main/docs/rules/on-function-explicit-return-type.md