Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions types/react/canary.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ export {};
declare const UNDEFINED_VOID_ONLY: unique symbol;
type VoidOrUndefinedOnly = void | { [UNDEFINED_VOID_ONLY]: never };

/**
* @internal
*/
interface ReactContextAsReactNode extends React.Context<React.ReactNode> {}

declare module "." {
interface ThenableImpl<T> {
then(onFulfill: (value: T) => unknown, onReject: (error: unknown) => unknown): void | PromiseLike<unknown>;
Expand Down Expand Up @@ -141,4 +146,23 @@ declare module "." {
onTransitionStart?: TransitionEventHandler<T> | undefined;
onTransitionStartCapture?: TransitionEventHandler<T> | undefined;
}

/**
* @internal Use `Awaited<ReactNode>` instead
*/
// Helper type to enable `Awaited<ReactNode>`.
// Must be a copy of the non-thenables of `ReactNode`.
type AwaitedReactNode =
| ReactElement
| string
| number
| Iterable<AwaitedReactNode>
| ReactPortal
| boolean
| null
| undefined;
interface DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES {
contexts: ReactContextAsReactNode;
promises: Promise<AwaitedReactNode>;
}
}
18 changes: 0 additions & 18 deletions types/react/experimental.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,6 @@ declare const UNDEFINED_VOID_ONLY: unique symbol;
type VoidOrUndefinedOnly = void | { [UNDEFINED_VOID_ONLY]: never };

declare module "." {
/**
* @internal Use `Awaited<ReactNode>` instead
*/
// Helper type to enable `Awaited<ReactNode>`.
// Must be a copy of the non-thenables of `ReactNode`.
type AwaitedReactNode =
| ReactElement
| string
| number
| Iterable<AwaitedReactNode>
| ReactPortal
| boolean
| null
| undefined;
interface DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES {
promises: Promise<AwaitedReactNode>;
}

export interface SuspenseProps {
/**
* The presence of this prop indicates that the content is computationally expensive to render.
Expand Down
28 changes: 28 additions & 0 deletions types/react/test/canary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -359,3 +359,31 @@ function formTest() {
event;
}}
/>;

// ReactNode tests
{
// @ts-expect-error
const render: React.ReactNode = () => React.createElement("div");
// @ts-expect-error
const emptyObject: React.ReactNode = {};
// @ts-expect-error
const plainObject: React.ReactNode = { dave: true };
const promise: React.ReactNode = Promise.resolve("React");
// @ts-expect-error plain objects are not allowed
<div>{{ dave: true }}</div>;
<div>{Promise.resolve("React")}</div>;

const asyncTests = async function asyncTests() {
const node: Awaited<React.ReactNode> = await Promise.resolve("React");
};

const RenderableContext = React.createContext<React.ReactNode>("HAL");
const NestedContext = React.createContext(RenderableContext);
let node: React.ReactNode = RenderableContext;
// @ts-expect-error TODO context values are recursively unwrapped so this should be allowed by types.
node = NestedContext;

const NotRenderableContext = React.createContext(() => {});
// @ts-expect-error
node: React.ReactNode = NotRenderableContext;
}
18 changes: 0 additions & 18 deletions types/react/test/experimental.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,24 +72,6 @@ function useEvent() {
);
}

// ReactNode tests
{
// @ts-expect-error
const render: React.ReactNode = () => React.createElement("div");
// @ts-expect-error
const emptyObject: React.ReactNode = {};
// @ts-expect-error
const plainObject: React.ReactNode = { dave: true };
const promise: React.ReactNode = Promise.resolve("React");
// @ts-expect-error plain objects are not allowed
<div>{{ dave: true }}</div>;
<div>{Promise.resolve("React")}</div>;

const asyncTests = async function asyncTests() {
const node: Awaited<React.ReactNode> = await Promise.resolve("React");
};
}

function elementTypeTests() {
const ReturnPromise = () => Promise.resolve("React");
const FCPromise: React.FC = ReturnPromise;
Expand Down
24 changes: 24 additions & 0 deletions types/react/ts5.0/canary.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ export {};
declare const UNDEFINED_VOID_ONLY: unique symbol;
type VoidOrUndefinedOnly = void | { [UNDEFINED_VOID_ONLY]: never };

/**
* @internal
*/
interface ReactContextAsReactNode extends React.Context<React.ReactNode> {}

declare module "." {
interface ThenableImpl<T> {
then(onFulfill: (value: T) => unknown, onReject: (error: unknown) => unknown): void | PromiseLike<unknown>;
Expand Down Expand Up @@ -141,4 +146,23 @@ declare module "." {
onTransitionStart?: TransitionEventHandler<T> | undefined;
onTransitionStartCapture?: TransitionEventHandler<T> | undefined;
}

/**
* @internal Use `Awaited<ReactNode>` instead
*/
// Helper type to enable `Awaited<ReactNode>`.
// Must be a copy of the non-thenables of `ReactNode`.
type AwaitedReactNode =
| ReactElement
| string
| number
| Iterable<AwaitedReactNode>
| ReactPortal
| boolean
| null
| undefined;
interface DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES {
contexts: ReactContextAsReactNode;
promises: Promise<AwaitedReactNode>;
}
}
18 changes: 0 additions & 18 deletions types/react/ts5.0/experimental.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,6 @@ declare const UNDEFINED_VOID_ONLY: unique symbol;
type VoidOrUndefinedOnly = void | { [UNDEFINED_VOID_ONLY]: never };

declare module "." {
/**
* @internal Use `Awaited<ReactNode>` instead
*/
// Helper type to enable `Awaited<ReactNode>`.
// Must be a copy of the non-thenables of `ReactNode`.
type AwaitedReactNode =
| ReactElement
| string
| number
| Iterable<AwaitedReactNode>
| ReactPortal
| boolean
| null
| undefined;
interface DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES {
promises: Promise<AwaitedReactNode>;
}

export interface SuspenseProps {
/**
* The presence of this prop indicates that the content is computationally expensive to render.
Expand Down
28 changes: 28 additions & 0 deletions types/react/ts5.0/test/canary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -359,3 +359,31 @@ function formTest() {
event;
}}
/>;

// ReactNode tests
{
// @ts-expect-error
const render: React.ReactNode = () => React.createElement("div");
// @ts-expect-error
const emptyObject: React.ReactNode = {};
// @ts-expect-error
const plainObject: React.ReactNode = { dave: true };
const promise: React.ReactNode = Promise.resolve("React");
// @ts-expect-error plain objects are not allowed
<div>{{ dave: true }}</div>;
<div>{Promise.resolve("React")}</div>;

const asyncTests = async function asyncTests() {
const node: Awaited<React.ReactNode> = await Promise.resolve("React");
};

const RenderableContext = React.createContext<React.ReactNode>("HAL");
const NestedContext = React.createContext(RenderableContext);
let node: React.ReactNode = RenderableContext;
// @ts-expect-error TODO context values are recursively unwrapped so this should be allowed by types.
node = NestedContext;

const NotRenderableContext = React.createContext(() => {});
// @ts-expect-error
node: React.ReactNode = NotRenderableContext;
}
18 changes: 0 additions & 18 deletions types/react/ts5.0/test/experimental.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,24 +72,6 @@ function useEvent() {
);
}

// ReactNode tests
{
// @ts-expect-error
const render: React.ReactNode = () => React.createElement("div");
// @ts-expect-error
const emptyObject: React.ReactNode = {};
// @ts-expect-error
const plainObject: React.ReactNode = { dave: true };
const promise: React.ReactNode = Promise.resolve("React");
// @ts-expect-error plain objects are not allowed
<div>{{ dave: true }}</div>;
<div>{Promise.resolve("React")}</div>;

const asyncTests = async function asyncTests() {
const node: Awaited<React.ReactNode> = await Promise.resolve("React");
};
}

function elementTypeTests() {
const ReturnPromise = () => Promise.resolve("React");
// @ts-expect-error Needs https://github.com/DefinitelyTyped/DefinitelyTyped/pull/65135
Expand Down