From 9c0e44b67ec9eddf2d754fe2e2dcfcfb26ec7b3f Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Fri, 21 Jun 2024 14:37:14 -0400 Subject: [PATCH 1/4] Simplify props types wip wip --- .../src/components/transition/transition.tsx | 6 ++---- .../src/utils/render.test.tsx | 6 ++++-- packages/@headlessui-react/src/utils/render.ts | 18 +++++++++++------- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/packages/@headlessui-react/src/components/transition/transition.tsx b/packages/@headlessui-react/src/components/transition/transition.tsx index d2d4189ab4..a911b4919f 100644 --- a/packages/@headlessui-react/src/components/transition/transition.tsx +++ b/packages/@headlessui-react/src/components/transition/transition.tsx @@ -318,7 +318,6 @@ function TransitionChildFn(null) @@ -444,6 +443,8 @@ function TransitionChildFn, ref: Ref ) { - // @ts-expect-error let { show, appear = false, unmount = true, ...theirProps } = props as typeof props let internalTransitionRef = useRef(null) let requiresRef = shouldForwardRef(props) @@ -610,10 +610,8 @@ function ChildFn return ( <> {!hasTransitionContext && hasOpenClosedContext ? ( - // @ts-expect-error This is an object ) : ( - // @ts-expect-error This is an object )} diff --git a/packages/@headlessui-react/src/utils/render.test.tsx b/packages/@headlessui-react/src/utils/render.test.tsx index f6844c5751..ac28cad01e 100644 --- a/packages/@headlessui-react/src/utils/render.test.tsx +++ b/packages/@headlessui-react/src/utils/render.test.tsx @@ -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 Contents diff --git a/packages/@headlessui-react/src/utils/render.ts b/packages/@headlessui-react/src/utils/render.ts index f3eda31e10..4106c4b683 100644 --- a/packages/@headlessui-react/src/utils/render.ts +++ b/packages/@headlessui-react/src/utils/render.ts @@ -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' @@ -40,17 +40,21 @@ export enum RenderStrategy { Hidden, } +type UnionToIntersection = (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 = XOR< - PropsForFeature, - PropsForFeature +export type PropsForFeatures = Expand< + UnionToIntersection< + | PropsForFeature + | PropsForFeature + > > export function render({ From 35e83272458c204498848f67870aef5a4a2f1ce0 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Mon, 24 Jun 2024 13:50:07 -0400 Subject: [PATCH 2/4] Remove unused types --- packages/@headlessui-react/src/types.ts | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/packages/@headlessui-react/src/types.ts b/packages/@headlessui-react/src/types.ts index cbd9b9a991..8bf566b4e4 100644 --- a/packages/@headlessui-react/src/types.ts +++ b/packages/@headlessui-react/src/types.ts @@ -2,12 +2,6 @@ import type { JSXElementConstructor, ReactElement, ReactNode } from 'react' export type ReactTag = keyof JSX.IntrinsicElements | JSXElementConstructor -// A unique placeholder we can use as a default. This is nice because we can use this instead of -// defaulting to null / never / ... and possibly collide with actual data. -// Ideally we use a unique symbol here. -let __ = '1D45E01E-AF44-47C4-988A-19A94EBAF55C' as const -export type __ = typeof __ - export type Expand = T extends infer O ? { [K in keyof O]: O[K] } : never export type PropsOf = TTag extends React.ElementType @@ -55,15 +49,4 @@ export type Props< ClassNameOverride & Overrides -type Without = { [P in Exclude]?: never } -export type XOR = T | U extends __ - ? never - : T extends __ - ? U - : U extends __ - ? T - : T | U extends object - ? (Without & U) | (Without & T) - : T | U - export type EnsureArray = T extends any[] ? T : Expand[] From f7dc58498f1adad3a84e1455029f970d5457eab1 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Mon, 24 Jun 2024 13:50:45 -0400 Subject: [PATCH 3/4] Remove test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit it’s no longer relevant --- packages/@headlessui-react/src/utils/render.test.tsx | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/packages/@headlessui-react/src/utils/render.test.tsx b/packages/@headlessui-react/src/utils/render.test.tsx index ac28cad01e..c1ede8354f 100644 --- a/packages/@headlessui-react/src/utils/render.test.tsx +++ b/packages/@headlessui-react/src/utils/render.test.tsx @@ -423,18 +423,6 @@ describe('Features.Static | Features.RenderStrategy', () => { ) } - // TODO: Can we "legit" test this? 🤔 - it.skip('should result in a typescript error', () => { - testRender( - // 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 - - Contents - - ) - }) - // To avoid duplication, and to make sure that the features tested in isolation can also be // re-used when they are combined. testStaticFeature(Dummy) From 964a47fd2f1ea7e089311787a24199fac63dc4c1 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Mon, 24 Jun 2024 13:52:34 -0400 Subject: [PATCH 4/4] Update changelog --- packages/@headlessui-react/CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/@headlessui-react/CHANGELOG.md b/packages/@headlessui-react/CHANGELOG.md index 6145da9ab5..6ffd78ba9e 100644 --- a/packages/@headlessui-react/CHANGELOG.md +++ b/packages/@headlessui-react/CHANGELOG.md @@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -- Nothing yet! +### Fixed + +- Fix issues spreading omitted props onto components ([#3313](https://github.com/tailwindlabs/headlessui/pull/3313)) ## [2.1.0] - 2024-06-21