Skip to content

Commit

Permalink
Simplify props types
Browse files Browse the repository at this point in the history
wip

wip
  • Loading branch information
thecrypticace committed Jun 21, 2024
1 parent d60ed6a commit 9c0e44b
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,6 @@ function TransitionChildFn<TTag extends ElementType = typeof DEFAULT_TRANSITION_
leaveFrom,
leaveTo,

// @ts-expect-error
...theirProps
} = props as typeof props
let container = useRef<HTMLElement | null>(null)
Expand Down Expand Up @@ -444,6 +443,8 @@ function TransitionChildFn<TTag extends ElementType = typeof DEFAULT_TRANSITION_
className:
classNames(
// Incoming classes if any
// @ts-expect-error: className may not exist because not
// all components accept className (but all HTML elements do)
theirProps.className,

// Apply these classes immediately
Expand Down Expand Up @@ -498,7 +499,6 @@ function TransitionRootFn<TTag extends ElementType = typeof DEFAULT_TRANSITION_C
props: TransitionRootProps<TTag>,
ref: Ref<HTMLElement>
) {
// @ts-expect-error
let { show, appear = false, unmount = true, ...theirProps } = props as typeof props
let internalTransitionRef = useRef<HTMLElement | null>(null)
let requiresRef = shouldForwardRef(props)
Expand Down Expand Up @@ -610,10 +610,8 @@ function ChildFn<TTag extends ElementType = typeof DEFAULT_TRANSITION_CHILD_TAG>
return (
<>
{!hasTransitionContext && hasOpenClosedContext ? (
// @ts-expect-error This is an object
<TransitionRoot ref={ref} {...props} />
) : (
// @ts-expect-error This is an object
<InternalTransitionChild ref={ref} {...props} />
)}
</>
Expand Down
6 changes: 4 additions & 2 deletions packages/@headlessui-react/src/utils/render.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -424,9 +424,11 @@ describe('Features.Static | Features.RenderStrategy', () => {
}

// TODO: Can we "legit" test this? 🤔
it('should result in a typescript error', () => {
it.skip('should result in a typescript error', () => {
testRender(
// @ts-expect-error static & unmount together are incompatible
// Properly setting up the types for this causes way more problems than it solves.
// Omit<…> has issues for instance when spreading the rest of the props on the component.
// @!ts-expect-error static & unmount together are incompatible
<Dummy show={false} static unmount>
Contents
</Dummy>
Expand Down
18 changes: 11 additions & 7 deletions packages/@headlessui-react/src/utils/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
type ReactElement,
type Ref,
} from 'react'
import type { Expand, Props, XOR, __ } from '../types'
import type { Expand, Props } from '../types'
import { classNames } from './class-names'
import { match } from './match'

Expand Down Expand Up @@ -40,17 +40,21 @@ export enum RenderStrategy {
Hidden,
}

type UnionToIntersection<T> = (T extends any ? (x: T) => any : never) extends (x: infer R) => any
? R
: never

type PropsForFeature<
TPassedInFeatures extends RenderFeatures,
TForFeature extends RenderFeatures,
TProps,
> = {
[P in TPassedInFeatures]: P extends TForFeature ? TProps : __
}[TPassedInFeatures]
> = TPassedInFeatures extends TForFeature ? TProps : {}

export type PropsForFeatures<T extends RenderFeatures> = XOR<
PropsForFeature<T, RenderFeatures.Static, { static?: boolean }>,
PropsForFeature<T, RenderFeatures.RenderStrategy, { unmount?: boolean }>
export type PropsForFeatures<T extends RenderFeatures> = Expand<
UnionToIntersection<
| PropsForFeature<T, RenderFeatures.Static, { static?: boolean }>
| PropsForFeature<T, RenderFeatures.RenderStrategy, { unmount?: boolean }>
>
>

export function render<TFeature extends RenderFeatures, TTag extends ElementType, TSlot>({
Expand Down

0 comments on commit 9c0e44b

Please sign in to comment.