diff --git a/change/@nova-react-test-utils-294e0e08-c819-4845-84ce-5ddf9d975afc.json b/change/@nova-react-test-utils-294e0e08-c819-4845-84ce-5ddf9d975afc.json new file mode 100644 index 0000000..88e81da --- /dev/null +++ b/change/@nova-react-test-utils-294e0e08-c819-4845-84ce-5ddf9d975afc.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "fix type for fragment keys", + "packageName": "@nova/react-test-utils", + "email": "stwilczy@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/nova-react-test-utils/package.json b/packages/nova-react-test-utils/package.json index 4df5056..6dd1b4e 100644 --- a/packages/nova-react-test-utils/package.json +++ b/packages/nova-react-test-utils/package.json @@ -40,7 +40,7 @@ "graphql": "^15.5.0", "invariant": "^2.2.4", "tslib": "^2.2.0", - "type-fest": "~2.19" + "type-fest": "^4.0.0" }, "devDependencies": { "@apollo/client": "^3.4.15", diff --git a/packages/nova-react-test-utils/src/shared/types.d-test.ts b/packages/nova-react-test-utils/src/shared/types.d-test.ts index 39a8fa0..3e78a11 100644 --- a/packages/nova-react-test-utils/src/shared/types.d-test.ts +++ b/packages/nova-react-test-utils/src/shared/types.d-test.ts @@ -254,6 +254,8 @@ interface PropsWithFragments { user: MockFragmentKey; regularProp: string; optionalProp?: number; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + anyProp: any; } interface MockQuery extends OperationType { diff --git a/packages/nova-react-test-utils/src/shared/types.ts b/packages/nova-react-test-utils/src/shared/types.ts index 9f17aee..4000aa2 100644 --- a/packages/nova-react-test-utils/src/shared/types.ts +++ b/packages/nova-react-test-utils/src/shared/types.ts @@ -1,11 +1,12 @@ import type { StoryObj } from "@storybook/react"; -import type { Simplify, RequiredKeysOf } from "type-fest"; +import type { Simplify, RequiredKeysOf, IfAny, SimplifyDeep } from "type-fest"; +import type { ComponentType } from "react"; /** * Utility type to extract the props of a React component. */ export type Props = - Component extends React.ComponentType ? P : never; + Component extends ComponentType ? P : never; /** * Utility type to return the keys of a component's props, where the value of the key is an object containing an optional " $data" property. @@ -14,7 +15,11 @@ export type Props = export type FragmentKeys = Props extends infer P ? Required<{ - [K in keyof P]: P[K] extends { " $data"?: unknown } ? K : never; + [K in keyof P]: IfAny< + P[K], + never, + P[K] extends { " $data"?: unknown } ? K : never + >; }>[keyof P] : never; @@ -55,13 +60,12 @@ type OptionalArgs = T extends { args?: infer A } // Omits Z from the Storybook "args" field of T type OmitFromArgs = Omit & - Simplify< + SimplifyDeep< (Record extends Omit, keyof Z> ? { args?: Omit, keyof Z> } : { args: Omit, keyof Z> }) & { args?: Omit, keyof Z>; - }, - { deep: true } + } >; // Check if keys of T are a subset of keys of P. Returns true if they are or union of keys that are not. @@ -89,19 +93,23 @@ export type ValidatedReferenceEntries< TComponent, TQuery extends { response: unknown }, > = - TComponent extends React.ComponentType + // The any here is important, changing to unknown or never would break inferring component + // eslint-disable-next-line @typescript-eslint/no-explicit-any + TComponent extends ComponentType ? FragmentKeys extends never ? Record unknown> : // Fragment keys must have correct type, other keys can be anything - Simplify<{ - [K in FragmentKeys]: ( - queryResult: TQuery["response"], - ) => FragmentKeyType | null | undefined; - } & { - [K in Exclude>]?: ( - queryResult: TQuery["response"], - ) => unknown; - }> + Simplify< + { + [K in FragmentKeys]: ( + queryResult: TQuery["response"], + ) => FragmentKeyType | null | undefined; + } & { + [K in Exclude>]?: ( + queryResult: TQuery["response"], + ) => unknown; + } + > : Record unknown>; export type StoryObjWithoutFragmentRefs = T extends { @@ -112,7 +120,7 @@ export type StoryObjWithoutFragmentRefs = T extends { }; }; } - ? C extends React.ComponentType + ? C extends ComponentType ? AreKeysSubset extends true ? OmitFromArgs, D> : ReferenceEntriesError> diff --git a/yarn.lock b/yarn.lock index 9a0cdfd..16a9f06 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6310,10 +6310,10 @@ type-fest@^0.21.3: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -type-fest@~2.19: - version "2.19.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" - integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== +type-fest@^4.0.0: + version "4.41.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.41.0.tgz#6ae1c8e5731273c2bf1f58ad39cbae2c91a46c58" + integrity sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA== type@^1.0.1: version "1.2.0"