🫥
Typescriptでfindの返り値の型が<| undefined>であることへの対処
以下のような状況のとき,findの返り値の型は,<Item | undefined>
になるが,selectedItemの型は,<Item | null>
であるので,型が一致せずエラーになる.
export type Item = {
id: number;
name: string;
};
export const useSelectItem = () => {
const [selectedItem, setSelectedItem] = useState<Item | null>(null);
const onSelectItem = useCallback((props: Props) => {
const { id, items } = props;
const targetItem = items.find((item) => item.id === id);
setSelectedUser(targetItem); // error
}, []);
return { onSelectItem, selectedItem };
};
解決法1
undefinedになりうる可能性のある値の直後にIF文で分岐を作って,Undefinedの場合の処理を書く.
export const useSelectItem = () => {
const [selectedItem, setSelectedItem] = useState<Item | null>(null);
const onSelectItem = useCallback((props: Props) => {
const { id, items } = props;
const targetItem = items.find((item) => item.id === id);
if (targetItem === undefined) {
console.error('item does not exist')
// 何らかのエラー処理
return;
}
setSelectedUser(targetItem);
}, []);
return { onSelectItem, selectedItem };
};
解決法2
targetItemの値がNullまたはUndefinedであれば,nullを明示的に設定することで型不一致を回避する.
(A ?? B)
は,AがNullまたはUndefinedのとき,Bが実行される.
export const useSelectItem = () => {
const [selectedItem, setSelectedItem] = useState<Item | null>(null);
const onSelectItem = useCallback((props: Props) => {
const { id, items } = props;
const targetItem = items.find((item) => item.id === id);
setSelectedUser(targetItem ?? null);
}, []);
return { onSelectItem, selectedItem };
};
解決法3
targetItemがUndefinedになる可能性はない,とTypescriptのコンパイラに伝える.
変数名!で,その値がUndefinedになることはないと伝える.
export const useSelectItem = () => {
const [selectedItem, setSelectedItem] = useState<Item | null>(null);
const onSelectItem = useCallback((props: Props) => {
const { id, items } = props;
const targetItem = items.find((item) => item.id === id);
setSelectedUser(targetItem!);
}, []);
return { onSelectItem, selectedItem };
};
Discussion