typescript - Tip korumasında (`hasOwnProperty`) `string`i `T`nin `keyof`una daraltma
Bir nesnenin anahtarı olması gereken bir string kullanıcı girdiğim var.
const validInputOptions = {
"admin": "Admin",
"guest": "Guest",
"restricted": "Restricted Guest",
"view_only": "Restricted Guest - View Only",
};
const userInput = getUserInput(); // <-- userInput is a string
verify(userInput); // <-- throws new error if user input is invalid
const option = validInputOptions[userInput]; // <-- tsc would still complain here `Element implicitly has an 'any' type because expression of type 'string' can't be used to index type ...`
Sorun, kullanıcı girişinin validInputOptions için güvenli bir şekilde indeks olarak kullanılabileceğini tsc'ye söylemektir
Cevap #1
İşte benim oluşturduğum tür koruyucu (typescript üzerinde resmi bir konu var https://github.com/microsoft/TypeScript/issues/12892, bu konu in operatörü ve hasOwnProperty için tsc'nin neden türü daraltmadığını açıklıyor)
const isKeyOf =
<ObjectType extends Record<PropertyKey, unknown>>
(object: ObjectType, property: PropertyKey): property is keyof ObjectType => {
return Object.prototype.hasOwnProperty.call(object, property);
};
yani bu kullanım şekli:
if (!isKeyOf(validInputOptions, userInput)) {
throw new Error(`invalid input`);
}
// now this is safe to use, userInput is narrowed to `keyof typeof validInputOptions`
const option = validInputOptions[userInput];
Cevap #2
Bu da işe yarıyor gibi görünüyor:
function isKeyOf<T extends object>(obj: T, key: PropertyKey): key is keyof T {
return obj.hasOwnProperty(key)
}
