reactjs - 打字稿编译器不强制泛型
问题描述
问题
我有一个减速器模型,其动作接受payload
预期的形状{ id: string, newValues: Partial<A_or_B> }
。在下面的代码中,A_or_B
当我声明内联时不强制执行类型newValues
;但是,如果我newValues
提前声明并为其分配属性,则会强制执行约束。即使声明为内联,我如何才能强制执行约束?A_or_B
newValues
有问题的代码
import { useContext } from "react";
import { AppDispatchContext } from "../src/AppProvider";
import { ActionTypes, A_or_B } from "./interfaces";
export default function App() {
const dispatch = useContext(AppDispatchContext);
const x: Partial<A_or_B> = {};
// Property 'color' does not exist on type
// 'Partial<A> | Partial<B>'.
// Property 'color' does not exist on type 'Partial<A>'.
x.color = "red";
dispatch({
type: ActionTypes.POINT_UPDATED,
// why can I assign a color to Partial<A>|Partial<B> if 'color'
// only exists on B?
payload: { id: "x", newValues: { color: "red" } }
});
}
代码沙盒链接
解决方案
union
这是大多数人在使用 typescript时遇到的常见问题。有些人将它们视为交集类型,而有些人希望它们表现得更像互斥类型。
但是,typescript 对联合类型有两种不同的解释,具体取决于您的用例。
特性
当您尝试访问联合类型的属性时,您只能访问联合的所有成员共有的属性。另一种说法是,您只能访问联合成员的属性的交集。
这可能是拗口,但打字稿文档给出了一个很好的类比来解释这一点:
例如,如果我们有一个房间里有戴帽子的高个子,而另一个房间里有讲西班牙语的人戴帽子,在组合这些房间后,我们对每个人的唯一了解就是他们必须戴帽子。
所以在属性访问的情况下,typescript 只允许访问属性的一个子集(没有来自用户的任何进一步提示),从而形成了一个交集。
成员资格(又名类型推断)
当涉及到类型推断时,编译器在允许匹配联合类型方面非常自由。从本质上讲,如果你想成为这个小组的一员,你只需要看起来像这个小组的成员之一。在这种情况下,您不必拥有与联合体的每个成员的属性相匹配的属性。
也许您的问题的解决方案是只使用交集类型x
:
const x: Partial<A&B> = {};
x.color = "red"; // works!
...
newValues: x; // also works
这解决了属性访问和成员资格的问题
推荐阅读
- firebase - Firebase 函数是否遵循 Firestore 安全规则?
- apache-nifi - NIFI - https 站点到站点 PeerSelector 连接拒绝
- c++ - 有没有办法重复循环?
- javascript - 简单的 Express/Node.js MVC 路由问题
- python - 如何在找到 QR 时停止扫描网络摄像头并使其再次扫描
- arduino - 了解用操纵杆控制 8x8 点阵的代码背后的逻辑
- javascript - 如何在 Css 中为文本设置字体?
- python - 从 Flask 传递到 Jinja2 时文件名中断
- google-sheets - 如何将公司财务信息输入 Google 表格
- python - 在 python 中抓取页面的一些帮助