¿Cómo puedo escribir un tipo Recursive NonNullable en Typescript?
Estoy tratando de crear una función que funcione como el get de lodash pero que tenga tipado.
Esto es lo que tengo hasta ahora:
function safeGet<T, R>(subject: T, select: (t: NonNullable<T>) => R): R | undefined {
try { return select(subject); }
catch { return undefined; }
}
// example use
interface MyType {
someKey: {
someValue: string | undefined;
} | undefined
}
let exampleSubject: MyType = /* ... */;
const gotSomeValue = safeGet(exampleSubject, s => s.someKey.someValue)
Esto funciona en parte, pero no elimina de manera recursiva lo indefinido. ¿Hay alguna manera de crear algún tipo de tipo NonNullable recursivo?
Respuesta #1
const RNN_ORIG = Symbol();
type RecursiveNonNullable1<T> = { [K in keyof T]: RecursiveNonNullable<T[K]> };
type RecursiveNonNullable<T> = RecursiveNonNullable1<NonNullable<T>> & {[RNN_ORIG]: T};
function safeGet<T, R extends { [RNN_ORIG]: unknown }>
(subject: T, select: (t: RecursiveNonNullable<T>) => R): R[typeof RNN_ORIG] | undefined {
try { return select(<any>subject); }
catch { return undefined; }
}
// example use
interface MyType {
someKey: {
someValue: string | undefined;
} | undefined
}
declare let exampleSubject: MyType;
const gotSomeValue = safeGet(exampleSubject, s => s.someKey.someValue)
