reactjs - Varsayılan isteğe bağlı değere sahip react props için koşullu tip


Koşullu özellik türlerine sahip olmak istiyorum

Koşullu türün içindeki isteğe bağlı prop'uma varsayılan bir değer vermeye çalıştığımda, türler bozuluyor

export type ChatBase = {
  id: string;
  title: string;
}

type ChatCardProps = { title: string; } &
  (
    | {
        chat: ChatBase & { createdBy: { displayName: string } };
        hideCreator?: false;
      }
    | {
        chat: ChatBase;
        hideCreator: true;
      }
  );

const Chat = ({ title, chat, hideCreator = false }: ChatCardProps) => {
  return (
    <div>
      <p>{title}</p>
      {!hideCreator && <p>{chat.createdBy.displayName}</p>}
      {/*                           ^? createdBy?: { displayName: string; } | undefined */}
    </div>
  )
}

const Chat2 = ({ title, chat, hideCreator }: ChatCardProps) => {
  return (
    <div>
      <p>{title}</p>
      {!hideCreator && <p>{chat.createdBy.displayName}</p>}
      {/*                          ^? createdBy?: { displayName: string; } */}
    </div>
  )
}

Varsayılan bir değer geçtiğimde neden mantık bozuluyor?

CodeSandbox: https://codesandbox.io/s/nameless-browser-hgshpz?file=/src/App.tsx:349-350

Cevap #1

Bunu tip dönüşümü kullanarak yapabilirsiniz, işte kod-sandbox parçacığınızın içinde bazı güncellemeler yaptığım sandbox linki

Bunun dışında, bunu generikler kullanarak yapabilirsiniz; işte bunun için referans kod parçacığı, ancak bu tüm kodu değiştirecek ve o durumda daha fazla çaba gerekecektir.

 type ChatType<HasDisplayName extends boolean> = HasDisplayName extends true
  ? ChatBaseWithdisplayName
  : ChatBaseWithoutDisplayName;

// Usage with a condition
const hasDisplayName = true; // Example condition

const chat: ChatType<typeof hasDisplayName> = {
  title: "Chat Title",
  // ... other properties based on the selected type
};

// Alternatively, without a condition (always uses ChatBaseWithdisplayName)
const chatAlwaysDisplayName: ChatType<true> = {
  title: "Chat Title",
  // ... other properties based on ChatBaseWithdisplayName
};

const chatNoDisplayName: ChatType<false> = {
  title: "Chat Title",
  // ... other properties based on ChatBaseWithoutDisplayName
};

Cevap #2

Kodunuz kısmi ve CardProps'in ne olduğunu tam olarak bilmiyorum, işe yarıyor gibi görünen küçültülmüş bir örnek yaptım. Bunu burada bulabilirsiniz.