组件变体的可辨识联合类型
使用可辨识联合类型对变体属性建模,让 TypeScript 强制检查有效的属性组合。
组件变体的可辨识联合类型 是 CoddyKit 上的免费 React Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。
变体属性的问题
一个组件如果使用可选属性来支持不同模式(例如,一个按钮既可以是链接,也可以是按钮),就可能出现无效的属性组合。没有判别联合类型,TypeScript 无法捕获这些问题。
什么是判别联合类型
判别联合类型是一组共享字面量类型字段(即判别字段)的联合类型。TypeScript 会根据该字段的值缩小类型范围。
type Shape =
| { kind: 'circle'; radius: number }
| { kind: 'rectangle'; width: number; height: number };
function area(shape: Shape): number {
if (shape.kind === 'circle') return Math.PI * shape.radius ** 2;
return shape.width * shape.height; // TS knows width/height exist here
}按钮与链接变体
在 as 或 variant 字段上使用判别联合类型,为多态组件建模,从而为每种情况强制执行正确的属性。
type ButtonProps =
| { as: 'button'; onClick: () => void; disabled?: boolean; children: React.ReactNode }
| { as: 'a'; href: string; target?: string; children: React.ReactNode };
function ActionButton(props: ButtonProps) {
if (props.as === 'button') {
return <button onClick={props.onClick} disabled={props.disabled}>{props.children}</button>;
}
return <a href={props.href} target={props.target}>{props.children}</a>;
}Alert 组件变体
为 Alert 建模,使每种严重级别类型都具有不同的必填数据。
type AlertProps =
| { type: 'success'; message: string }
| { type: 'error'; message: string; onRetry: () => void }
| { type: 'warning'; message: string; details?: string };
function Alert(props: AlertProps) {
if (props.type === 'error') {
return (
<div className="alert error">
<p>{props.message}</p>
<button onClick={props.onRetry}>Retry</button>
</div>
);
}
return <div className={`alert ${props.type}`}>{props.message}</div>;
}在事件处理函数中缩小类型范围
判别联合类型也适用于事件驱动的数据——非常适合状态机或基于操作的状态。
type LoadingState<T> =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'success'; data: T }
| { status: 'error'; error: Error };
function DataView<T>({ state }: { state: LoadingState<T> }) {
if (state.status === 'loading') return <Spinner />;
if (state.status === 'error') return <p>{state.error.message}</p>;
if (state.status === 'success') return <pre>{JSON.stringify(state.data)}</pre>;
return null;
}使用 never 进行穷尽检查
在默认分支中添加 never 检查。如果添加了新的联合成员却没有处理它,TypeScript 就会报告错误。
function assertNever(x: never): never {
throw new Error('Unhandled case: ' + x);
}
function renderIcon(type: AlertProps['type']) {
switch (type) {
case 'success': return <CheckIcon />;
case 'error': return <XIcon />;
case 'warning': return <WarnIcon />;
default: return assertNever(type); // TS error if a case is missing
}
}用于 API 响应的判别联合类型
将 API 响应结构建模为判别联合类型,这样调用方无需进行类型断言,就能处理成功和错误路径。
type ApiResult<T> =
| { ok: true; data: T }
| { ok: false; error: string; code: number };
async function fetchUser(id: string): Promise<ApiResult<User>> {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) return { ok: false, error: 'Not found', code: res.status };
return { ok: true, data: await res.json() };
}用于缩小类型范围的类型守卫
在判别字段不是简单相等检查的复杂场景中,可以使用自定义类型守卫来缩小联合类型的范围。
function isSuccess<T>(result: ApiResult<T>): result is { ok: true; data: T } {
return result.ok === true;
}
const result = await fetchUser('1');
if (isSuccess(result)) {
console.log(result.data.name); // TS knows data exists
}避免可选属性堆积
如果不使用判别联合类型,组件就会积累一些只有在特定组合中才有效的可选属性——这既令人困惑,又缺乏类型约束。判别联合类型可以消除不可能的状态。
// Bad: optional prop soup — invalid combos allowed:
interface BadProps {
href?: string;
onClick?: () => void;
disabled?: boolean;
}
// Good: only valid combos via discriminated union:
type GoodProps =
| { as: 'a'; href: string }
| { as: 'button'; onClick: () => void; disabled?: boolean };组合联合类型
使用 &(交叉类型)将共享属性添加到联合类型的所有成员中。
type BaseProps = { className?: string; children: React.ReactNode };
type ButtonVariant =
| (BaseProps & { variant: 'primary'; onClick: () => void })
| (BaseProps & { variant: 'link'; href: string });运行时判别
React 在运行时使用判别字段来渲染正确的界面。TypeScript 在编译时使用它来强制执行正确的属性用法。这两个层面都受到保护。
快速检查
判别联合类型中的判别字段是什么?
回顾
判别联合类型通过共享一个字面量类型的判别字段,为具有互斥属性集合的组件建模。在默认分支中使用 never 进行穷尽检查。它们消除了可选属性所允许的无效属性组合,使组件能够自我说明并确保类型安全。
用 AI 导师学习 React — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 88
- 课程
- 324
常见问题解答
「组件变体的可辨识联合类型」课时是免费的吗?
是的 — 「组件变体的可辨识联合类型」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。
「组件变体的可辨识联合类型」这节课中我会学到什么?
使用可辨识联合类型对变体属性建模,让 TypeScript 强制检查有效的属性组合。 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 React Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「组件变体的可辨识联合类型」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 React Academy 课中编写并运行代码吗?
能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。