useMemo 返回类型错误,但 tsc 不会显示错误?

tak*_*zzy 8 typescript reactjs react-hooks

const labelTypeMap = useMemo<Record<'between' | 'inner', string>>(
  () => ({
    between: formatMessage({ id: 'addGroup' }),
    inner: '+',
    aaa: 123, // no error here
  }),
  []
);
Run Code Online (Sandbox Code Playgroud)

正如代码所示,aaa即使它与 useMemo 的返回类型不匹配,也没有错误。任何帮助都感激不尽。

cyc*_*130 9

这是仍然演示该问题的简化版本:

const labelTypeMap: Record<"between" | "inner", string> = (() => ({
    between: "xxx",
    inner: "+",
    aaa: 123,
}))();
Run Code Online (Sandbox Code Playgroud)

问题在于,Typescript 通常允许对象具有额外的属性。毕竟,具有额外属性的对象与基本类型兼容(在面向对象的意义上)只有当您使用类似的动态内省功能时,才会发生意外Object.keys

这种灵活性的唯一例外是当您尝试直接分配对象文字时:

const labelTypeMap: Record<"between" | "inner", string> = {
    between: "xxx",
    inner: "+",
    aaa: 123, // Error as expected
};
Run Code Online (Sandbox Code Playgroud)

现在它会像预期的那样抱怨。

因此,解决您的问题的一种可能的解决方案是:

const labelTypeMap = useMemo(() => {
    const result: Record<"between" | "inner", string> = {
        between: "xxx",
        inner: "+",
        aaa: 123, // Error as expected
    };

    return result;
}, []);
Run Code Online (Sandbox Code Playgroud)

这也有效:

const labelTypeMap = useMemo(
    (): Record<"between" | "inner", string> => ({
        between: "xxx",
        inner: "+",
        aaa: 123, // Error as expected
    }),
    [],
);
Run Code Online (Sandbox Code Playgroud)