javascript 如果已经使用了一个接口,是否有必要在useState中再次定义类型?

5fjcxozz  于 2023-10-14  发布在  Java
关注(0)|答案(2)|浏览(117)

考虑以下代码:
IAppStateProps.ts

import {INoteProps} from "./INoteProps";

export interface IAppStateProps {
  notesData: INoteProps[];
}

然后在这里使用它:useAppState.ts

import {INoteProps} from "./interfaces/INoteProps";
import {IAppStateProps} from "./interfaces/IAppStateProps";
export const useAppState = (): IAppStateProps => {
  const [notesData, setNotesData] = useState<INoteProps[]>([]);
  ...more code
  return {
    notesData
  }
};

我的问题是,既然我将useAppState的返回类型定义为IAppStateProps,并且它知道notesData应该返回INoteProps[],那么是否有必要在const [notesData, setNotesData] = useState<INoteProps[]>([]);中重新定义返回类型?

mwg9r5ms

mwg9r5ms1#

既然我把useAppState的返回类型定义为IAppStateProps,并且它知道notesData应该返回INoteProps[],那么是否需要在const [notesData,setNotesData] = useState<INoteProps[]>([])中重新定义返回类型;?
是的。TypeScript无法按照您描述的方向推断它。如果你在调用useState时不使用类型参数,而是使用一个空数组作为初始值,TypeScript会将never[]推断为类型,这意味着你不能用真实的数据调用setNotesData

// Stand-in for `INoteProps`, since it's not defined in the question
interface INoteProps {
    something: string;
}
// ...
export const useAppState = (): IAppStateProps => {
    const [notesData, setNotesData] = useState([]);

    useEffect(() => {
        setNotesData([
            {something: "cool"} // <== Error: Type '{ something: string; }' is 
                                // not assignable to type 'never'. (2322)
        ])
    }, []);

    return {
        notesData
    };
};

操场上的错误

如果你愿意,你可以用另一种方式推断它,通过在useAppState上去掉返回类型注解:

export const useAppState = () => {
    const [notesData, setNotesData] = useState<INoteProps[]>([]);

    useEffect(() => {
        setNotesData([
            {something: "cool"} // <== Works
        ])
    }, []);

    return {
        notesData
    };
};

Playground示例
TypeScript会将返回类型推断为{ notesData: INoteProps[]; }。由于TypeScript的类型系统是 * 结构化的 *(基于类型的 * 形状 *)而不是 * 名义化的 *(基于类型的名称),这与IAppStateProps相同。
但是,您可能不想这样做,因为意外更改函数返回类型的错误编辑不会被TypeScript捕获。在实践中,我发现推断返回类型对于非常短,简单的函数是好的,但对于任何超出此范围的事情,我需要指定返回应该是什么的安全网,以便编辑意外更改它会被及早捕获。您的里程可能会有所不同。:-)

btxsgosb

btxsgosb2#

如果我没理解错的话。不,您不需要指定它。当你调用useAppState时,它应该返回一个具有notesData属性的对象,该属性是一个数组。

相关问题