Saltar al contenido
Hacer dos formas de props mutuamente excluyentes

    ↑↓ mover · ⏎ abrir · esc cerrar

    Patrones

    ¿Cómo acepto `href` u `onClick` pero rechazo objetos que proporcionan ambos?

    Une las dos formas y añade las claves únicas del otro lado como propiedades opcionales `never`.

    La receta

    type Without<T, U> = {
      [K in Exclude<keyof T, keyof U>]?: never
    }
    
    type XOR<T, U> =
      | (T & Without<U, T>)
      | (U & Without<T, U>)
    
    type LinkProps = XOR<
      { href: string },
      { onClick: () => void }
    >

    La compilación compila esto y comprueba cada resultado de abajo.

    Cómo funciona

    1. 01
      [K in Exclude<keyof T, keyof U>]?: never

      Las claves únicas de la rama opuesta pueden faltar, pero nunca contener un valor.

    2. 02
      | (U & Without<T, U>)

      Cada miembro de la unión combina su forma obligatoria con una prohibición de la otra.

    Lo que obtienes

    Dónde falla

    Es más claro para dos formas pequeñas. Los tipos grandes y solapados producen diagnósticos ruidosos, y `exactOptionalPropertyTypes` cambia si un `undefined` explícito satisface un `never` opcional.

    Conclusión

    Usa `never` opcional para decir que una propiedad pertenece a la otra rama y no debe aparecer aquí.

    Véase también

    Patrones