Я пытаюсь написать определяемый пользователем тип защиты , который проверяет, имеет ли данное значение все свойства в данном массиве.
Я вызываю эту функцию hasAll
и его реализация и использование в Javascript будут выглядеть следующим образом:
function hasAll(obj, keysToCheck) {
if (!obj) return false;
for (const key of keysToCheck) {
const value = obj[key];
if (value === null) return false;
if (value === undefined) return false;
}
return true;
}
hasAll({ foo: 'test', bar: 5 }, ['foo', 'bar']); // true
hasAll({ foo: 'test', bar: 5 }, ['foo', 'bar', 'baz']); // false
Теперь я пытаюсь превратить вышеуказанную функцию в охранник типа . Это то, что у меня есть:
// this _almost_ works ?
type Nullable<T> = T | null | undefined;
type RemoveNullables<T, K extends keyof T> = {
[P in K]-?: T[P] extends Nullable<infer U> ? U : T[P];
};
function hasAll<T, K extends keyof NonNullable<T>>(
obj: T,
keysToCheck: K[],
): obj is RemoveNullables<NonNullable<T>, K> {
// but i'm getting an error here ???
if (!obj) return false;
const nonNullableObj = obj as NonNullable<T>;
for (const key of keysToCheck) {
const value = nonNullableObj[key];
if (value === null) return false;
if (value === undefined) return false;
}
return true;
}
export default hasAll;
ссылка на игровую площадку
Сообщение об ошибке:
A type predicate's type must be assignable to its parameter's type.
Type 'RemoveNullables<NonNullable<T>, K>' is not assignable to type 'T'.
I ' я прочитал этот ответ с хорошим объяснением, однако это не очень помогает моему делу.
Я хочу явно заявить, что мой тип T
будет соответствовать RemoveNullables<NonNullable<T>, K>
после его запуска через эту функцию. Меня не волнует, можно ли присвоить T
для RemoveNullables<NonNullable<T>, K>
(если это имеет смысл).
- Я поступаю неправильно? Есть ли лучший способ написать этот тип защиты?
- Если этот подход хорош, как я могу сказать машинописи, что мне все равно, если защита типа сама по себе "небезопасна"?