reactjs - Typescript 编译器不强制执行泛型

标签 reactjs typescript generics

问题

我有一个 reducer 模型,其操作接受 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" } }
  });
}

CodeSandbox 链接

CodeSandbox Link Here

最佳答案

这是大多数人遇到的常见问题 union在 typescript 中输入。有些人将它们视为交集类型,而有些人希望它们的行为更像互斥类型。

但是,TypeScript 对联合类型有两种不同的解释,具体取决于您的用例。

属性

当您尝试访问联合类型的属性时,您只能访问联合所有成员共同的属性。另一种说法是,您只能访问联合成员属性的交集

这可能有点拗口,但 typescript 文档给出了一个很好的 analogy解释一下:

For example, if we had a room of tall people wearing hats, and another room of Spanish speakers wearing hats, after combining those rooms, the only thing we know about every person is that they must be wearing a hat.

因此,在属性访问的情况下,TypeScript 仅允许访问属性的子集(无需用户提供任何进一步的提示),从而形成交集。

成员资格(又名类型推断)

在类型推断方面,编译器对于允许匹配联合类型的内容相当自由。本质上它是说,如果你想成为这个群体的一员,你只需看起来像这个群体的成员之一。在这种情况下,您不必拥有与联合体每个成员的属性相匹配的属性。


也许问题的解决方案是仅使用 x 的交集类型:

const x: Partial<A&B> = {};
x.color = "red"; // works!

...
newValues: x; // also works

这解决了属性(property)访问成员身份的问题

关于reactjs - Typescript 编译器不强制执行泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69330740/

相关文章:

generics - TypeScript类型参数实现多个接口(interface)

c# - 如何检查适用于字符串的通用对象是否相等

javascript - 如果在 React Native 中未选中所有复选框,如何禁用按钮

javascript - Redux:API 数据响应按点击排序

typescript - 键入所有可能的字符串以使用accessibilityRole?

javascript - 如何使用 window.scrollTo 在元素内滚动?

reactjs - 如何在 React 中为 AWS amplify GraphQL 响应设置 typescript 类型?

java - 泛型以及在实现 Iterable Interface 的类中使用新创建的方法

javascript - 使用 JavaScript 或 TypeScript 使用react?

reactjs - 使用 React Hook,尝试使用 forEach 获取多个数据