Я не знаю, покупает ли что-то вроде no-unsafe-any слишком много внутри реализации защиты определенного пользователем типа , поскольку обычно весь смысл такогозащита типа должна позволить компилятору сузить значения, которые он обычно не может сделать с помощью встроенного сужения потока управления.Я бы, конечно, понял, приостановив правило линтера внутри такой реализации.
Но я думаю, что вы можете получить почти то поведение, которое вы ищете, вот так:
function isIterable(obj: unknown): obj is Iterable<unknown> {
if ((typeof obj !== 'object') || (obj === null)) return false;
// obj is now type object
const wObj: { [Symbol.iterator]?: unknown } = obj; // safely widen to wObj
return typeof wObj[Symbol.iterator] === 'function';
}
Это несколько обручейчтобы прыгнуть, но идея состоит в том, чтобы использовать сужение потока управления для сужения unknown
до object
, а затем расширить object
специально для типа с необязательным свойством, которое вы пытаетесь проверить (это происходит путем введения новой переменной).И, наконец, проверьте тип этого свойства в расширенном типе.Поскольку ключ свойства, который вы проверяете, является символьным типом, вам нужно упомянуть конкретное имя свойства в расширенном типе.Если ключ свойства является строкой, вы можете использовать подпись индекса строки :
function isPromise(obj: unknown): obj is Promise<unknown> {
if ((typeof obj !== 'object') || (obj === null)) return false;
// obj is now type object
const wObj: {[k: string]: unknown} = obj; // safely widen to wObj
return typeof wObj.then === 'function';
}
В любом случае, я надеюсь, что это приблизит вас к вашей цели.Удачи!