这是一个 TypeScript 和 react-hook-form
相关的核心问题。
总结:
类型 | 含义 | 场景 |
---|---|---|
keyof T |
T 的所有键的联合类型 | 你只关心字段名,字段可以是任意嵌套层级 |
Path<T> |
react-hook-form 的类型工具,支持嵌套字段 |
用于 Controller 、useForm 时更准确的字段路径 |
🔹 keyof T
是什么?
ini
type FormData = {
name: string;
age: number;
};
type Keys = keyof FormData; // "name" | "age"
keyof T
返回的是对象T
的顶层键名。- 不支持嵌套字段,比如
user.name.first
这样的路径。
🔹 Path<T>
是什么?
这是 react-hook-form
提供的一个递归类型工具 ,它能解析嵌套对象的完整路径字符串(string literal),比如:
ini
type FormData = {
user: {
name: {
first: string;
last: string;
};
age: number;
};
};
使用 Path<FormData>
,可以得到类型安全的字段路径:
bash
type P = Path<FormData>;
// "user" | "user.name" | "user.name.first" | "user.name.last" | "user.age"
使用建议
需求 | 推荐使用类型 | 说明 |
---|---|---|
字段是平的、非嵌套 | keyof T |
简单、直接 |
用在 react-hook-form 中的 name 属性 |
Path<T> |
支持嵌套路径,类型安全 |
想做通用组件,支持嵌套字段 | Path<T> |
更通用 |
构建 UI,仅获取字段列表 | keyof T |
如果不绑定 form state,用它 |
示例对比
csharp
interface FormData {
name: string;
settings: {
timezone: string;
};
}
const field1: keyof FormData = 'name'; // ✅ OK
const field2: keyof FormData = 'settings'; // ✅ OK
const field3: keyof FormData = 'settings.timezone'; // ❌ 错误!
const path1: Path<FormData> = 'name'; // ✅ OK
const path2: Path<FormData> = 'settings'; // ✅ OK
const path3: Path<FormData> = 'settings.timezone'; // ✅ OK ✅ ✅ ✅
实战建议
在封装组件,等绑定 react-hook-form
的组件时,请统一使用:
css
name: Path<T>;
因为这些组件都需要传给 Controller
,它的 name
参数类型就是 Path<T>