事象
ユーザによってはemailを持たない、という型定義をしたときに、hasOwnPropertyでは型ガードが効かずエラーになってしまった
type UserInfo = {
username: string;
attributes: GuestUserAttributes | PromotedUserAttributes;
};
type GuestUserAttributes = {
sub: string;
};
type PromotedUserAttributes =
| GuestUserAttributes
| {
email: string;
};{userInfo && userInfo.attributes.hasOwnProperty('email') && (
<Text>{userInfo.attributes.email}</Text>
)}
//Property 'email' does not exist on type 'PromotedUserAttributes'.
// Property 'email' does not exist on type 'GuestUserAttributes'.ts(2339)解決
in演算子を使う
hasOwnPropertyは型ガードが実装されていないが、in演算子は型ガードとして動く。
{userInfo && 'email' in userInfo.attributes && (
<Text>{userInfo.attributes.email}</Text>
)}hasOwnPropertyを拡張する
あるいは、Object型のinterfaceを拡張してhasOwnPropertyに型ガードを実装する方法もある
// declare global { // need this declaration if in a module
interface Object {
hasOwnProperty<K extends PropertyKey>(key: K): this is Record<K, unknown>;
}
// } // need this declaration if in a moduleWhy does Typescript treat object.hasOwnProperty("key") as essentially different from "key" in object