es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo distinguir `(() => any) | undefined` de solo `() => any` en TypeScript?

Tengo dos tipos: (() => any) | undefined y () => any. Me gustaría extraer el tipo de retorno de la función, pero solo si el valor no es definitivamente indefinido.

He intentado lo siguiente:

type IsUndefined<t> = T extends (() => any) ? "no" : "yes";

Pero esto resuelve a "yes" | "no" cuando el tipo no es indefinido. Quiero detectar la diferencia entre estos tipos sin crear una unión.

Consulta el siguiente enlace del playground para ver un ejemplo.

Esa es la historia corta, la historia larga es que tengo una estructura como la siguiente:

type MyStruct = {
    optionalHook?: ((...args: any) => any) | undefined,
    requiredHook: (...args: any) => any,
}

Me gustaría extraer el tipo de retorno del gancho opcional, pero solo cuando exista. Me gustaría extraer el tipo de retorno del gancho requerido en caso contrario.

Consulta el siguiente enlace del playground para ver un ejemplo más completo.

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para extraer el tipo de retorno de una función solo si el valor definitivamente no es indefinido, puede crear un alias de tipo usando tipos condicionales. Aquí tienes un ejemplo:

    type FunctionReturnType<t> = T extends (() => infer R) ? (undefined extends R ? never : R) : never;
    

    El alias de tipo FunctionReturnType toma un valor de tipo T y verifica si se extiende a un tipo de función utilizando un tipo condicional. Si es un tipo de función, utilizamos la palabra clave infer para extraer el tipo de retorno de la función en una nueva variable de tipo R. Luego verificamos si undefined se puede asignar a R. Si es así, devolvemos never, lo que significa que el valor definitivamente no es indefinido. De lo contrario, devolvemos R, el tipo de retorno real de la función.

    En el ejemplo de MyStruct, puedes usar el alias de tipo FunctionReturnType para extraer el tipo de retorno del hook opcional solo si existe, y utilizar el tipo de retorno del hook obligatorio en caso contrario. Aquí tienes una versión actualizada de la estructura:

    type MyStruct = {
        optionalHook?: (() => any) | undefined,
        requiredHook: () => any,
    }
    
    type ExtractReturnType<t, k="" extends="" keyof="" t=""> = K extends keyof T ? (undefined extends ReturnType<t[k]> ? ReturnType<t['requiredhook']> : ReturnType<t[k]>) : never;
    
    type OptionalReturnType = ExtractReturnType<mystruct, 'optionalhook'="">; // () => void
    type RequiredReturnType = ExtractReturnType<mystruct, 'requiredhook'="">; // () => any
    

    El alias de tipo ExtractReturnType toma un tipo genérico T y un tipo literal de cadena K, que es una clave de T. Primero verificamos si K es una clave de T utilizando otro tipo condicional. Si lo es, verificamos si el tipo de retorno de T[K] (es decir, el tipo de la propiedad correspondiente a K) se puede asignar a undefined. Si es así, devolvemos el tipo de retorno de la propiedad requiredHook de MyStruct. De lo contrario, devolvemos el tipo de retorno real de T[K].

    Usando ExtractReturnType, puedes extraer el tipo de retorno del hook opcional solo si existe, y utilizar el tipo de retorno del hook obligatorio en caso contrario. En el ejemplo anterior, el alias de tipo OptionalReturnType devuelve () => void porque el tipo de retorno del hook opcional definitivamente no es indefinido. El alias de tipo RequiredReturnType devuelve () => any porque el tipo de retorno del hook opcional es indefinido.</mystruct,></mystruct,></t[k]></t[‘requiredhook’]></t[k]></t,>

Comments are closed.