如何缩小 SVG 元素联合的类型

2024-03-21

我正在使用 React 设置对 svg 元素的引用,该元素可能是<rect>, <polygon> or <ellipse>.

我有这样的声明:

const shapeRef = useRef<SVGPolygonElement | SVGEllipseElement | SVGRectElement>(null);

但是当我尝试将其设置为<ellipse>像这样的元素:

<ellipse
  cx={width / 8}
  cy={-sideDimension(y) / 8}
  rx={width}
  ry={height}
  ref={shapeRef}
/>

我收到此错误:

类型“RefObject”不可分配给类型“string |” ((实例: SVG椭圆元素 | null) => void) |参考对象 | 空 |不明确的'。类型“RefObject”不可分配给类型 '参考对象'。 类型 'SVGPolygonElement | SVG椭圆元素 | SVGRectElement' 不可分配给类型“SVGEllipseElement”。 类型“SVGPolygonElement”缺少类型“SVGEllipseElement”的以下属性:cx、cy、rx、ryts(2322)

我对此的理解是,我需要以某种方式缩小类型才能使其工作,否则使用此引用的每个对象都必须具有联合的所有属性。


你是对的。 Typescript 会给你这个错误,因为它不知道应该考虑哪一种类型shapreRef as.

IMO 的最佳解决方案是使用类型保护装置 https://www.typescriptlang.org/docs/handbook/advanced-types.html. A 类型保护是检查变量是否属于某种类型的打字稿方法。对于联合类型,这使打字稿能够理解某些东西属于特定类型。

例如,在您的情况下,它可能是这样的:

interface IEllipse {
  attr1: string;
  attr2: string;
}

interface IRect {
  attr3: string;
  attr4: string;
}

type SvgShape = IEllipse | IRect | IPolygon;

function isEllipse(shape: SvgShape): shape is IEllipse {
    return (shape as IEllipse).attr1 !== undefined;
}

请注意,返回类型是shape is IEllipse。这意味着打字稿将在这里解释一个真实的返回值,就好像shape is an IEllipse.

然后,无论您想在何处使用SvgShape,您可以检查哪种类型SvgShape是的,打字稿应该基于此知道类型:

// ...
render() {
  const shape: SvgShape = this.getCurrentShape();

  if (isEllipse(shape)) {
    // typescript should KNOW that this is an ellipse inside this if
    // it will accept all of Ellipse's attribute and reject other attributes
    // that appear in other shapes

    return <ellipse .../>;
  } else if (isRect(shape)) {
    // typescript should interpet this shape as a Rect inside the `if`

    return <rect ... />;
  } else {
    // typescript will know only one subtype left (IPolygon)

    return <polygon points="..." />;
  }
}
// ...

为什么不只是一个交叉点类型?

嗯...交集类型更适合每种类型(矩形、多边形等)在新项目中具有完全相同的属性的情况。 例如:

type Inter = IRect & IPolygon & IEllipse;

意味着一个Inter类型是IRect and IPolygon and IEllipse。这意味着该类型的对象将具有所有三种类型的所有成员。 因此,尝试访问该属性points(存在于IPolygon)实际上是一个形状IRect,将表现得好像该属性存在于此(我们不希望如此)

您将主要看到用于混合的交集类型和其他不适合经典面向对象模型的概念。

如何与useRef一起使用?

type SvgShape = SVGPolygonElement | SVGEllipseElement | SVGRectElement;

const shapeRef = useRef<SvgShape>(null);

function isEllipseRef(shapeRef: MutableRefObject<SvgShape>): shapeRef is MutableRefObject<IEllipse> {
  const shape: SvgShape = shapeRef.current;
  return (shape as IEllipse).attr1 !== undefined;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何缩小 SVG 元素联合的类型 的相关文章

  • 如果一个对象结构与另一个对象结构不匹配/不匹配,如何引发异常

    我将读取格式正确的用户输入对象 也就是说 输入对象现在可以具有接口中未定义的任何键或子结构 如果用户提供了无效的对象 我如何抛出异常 预定义接口 export interface InputStructureInterface tableN
  • 没有 Props 的 TypeScript React State

    我想利用 TypeScript 中的静态和强类型 但仅限于状态 因为我不打算采用任何道具 当我尝试传递接口时 最终出现错误 import as React from react import Link from react router d
  • 在 javascript 文件中设置 firebase-admin sdk

    我的最终目标是使用用户 ID 获取用户电子邮件 到目前为止 我发现我需要使用 firebase admin SDK 现在我有这个代码 var admin require firebase admin var serviceAccount r
  • React 应用程序中的 addEventListener 不起作用

    一些背景 我正在尝试消费自定义网络组件在 React 应用程序中并尝试监听来自 Web 组件的事件 我相信您不能只在自定义 Web 组件上以通常的反应方式处理事件 i e
  • React 在同一组件中渲染多个模态

    我对 React 和一般编码都很陌生 我试图在同一组件中渲染多个模态 但它们都是同时渲染的 因此看起来所有链接都在最后一个模态中渲染文本 这是状态设置的地方 class Header extends React Component cons
  • ReactJS - Redux Form - 如何根据单选字段元素有条件地显示/隐藏元素?

    我对 Redux 比较陌生 我有一个表单 其中有一些无线电输入 是 或 否 基本上 我想根据该无线电输入选择有条件地显示包含另一个 redux 表单字段的另一个元素 有直接的方法可以做到这一点吗 我想检查一下formProps site v
  • 找不到“节点”的类型定义文件

    更新 Angular Webpack 和 TypeScript 后出现奇怪的错误 知道我可能会错过什么吗 当我使用 npm start 运行应用程序时 出现以下错误 at loader Cannot find type definition
  • VSCode TypeScript 问题Matcher `$tsc-watch` 未观看

    我试图避免使用watch true in a tsconfig json配置 通过 VSCode 的任务 我正在使用基本问题匹配器 tsc watch但它没有启动tsc构建时处于监视模式 我正在添加gulp支持 我看到有gulp watch
  • D3 将现有 SVG 字符串(或元素)追加(插入)到 DIV

    我到处寻找这个问题的答案 并找到了一些我认为可能有用的资源 但最终没有让我找到答案 这里有一些 外部SVG http bl ocks org mbostock 1014829 嵌入SVG https stackoverflow com qu
  • 使用 React.forwardRef 与自定义 ref prop 的价值

    我看到React forwardRef从反应文档来看 似乎是将引用传递给子功能组件的认可方式 const FancyButton React forwardRef props ref gt
  • 可下载文件 - 盖茨比

    由于某种原因 尝试下载文件时失败 我尝试了几种不同的方法 但都失败了 我读过一些关于 pdf word 文件在盖茨比中被 禁止 的内容 默认 a href route to file a 好像不行 显示下载失败 任何帮助表示赞赏 See 将
  • Typescript:通用到特定类型

    我有一个通用类型 type GenericType key string prop1 string prop2 string prop3 number 我使用通用类型来帮助构建 类型检查我创建的新对象 const Obj1 GenericT
  • 如何使用 Typescript 的 socket.IO 客户端类型定义?

    我已经使用 SocketIO 客户端安装了 Typescript 定义 npm install types socket io client 但在 VS Code 中我仍然遇到类型错误 let socket SocketIOClientSt
  • 您在 javascript Web 应用程序中使用的第三方 API ApiKey 存储在哪里?

    如何以及在何处存储您在 javascript Web 应用程序中使用的第三方 API ApiKey 又名 AppId AppSecret AppKey 如果它用于获取 URL 并且在浏览器网络选项卡中可见 我是否应该对其保密 示例 在我的
  • 如何在 React 中测试表单提交?

    我有以下 React 组件 export default class SignUpForm extends React Component doSignupForm event Some API call render return div
  • “同态映射类型”是什么意思?

    我在一些 TypeScript PR 中看到过 同态映射类型 这个术语 这是一个例子 https github com microsoft TypeScript pull 21919 https github com microsoft T
  • 在 Angular 中使用 Vue 组件

    我有一个用 Vue 构建的项目 我想在 Angular 应用程序中重用 Vue 应用程序中的组件 这样我就不必从头开始重建每个组件 我在medium上看到了这个教程 如何在 Angular 应用程序中使用 Vue 2 0 组件 https
  • WordPress 包含 SVG 文件错误

    我使用 PHP 和 WordPress 在本地主机上 我可以毫无问题地包含 SVG 文件 但在实时服务器上 我尝试包含一个 SVG 文件以便能够使用 CSS 对其进行样式设置 我收到此错误消息 Parse error syntax erro
  • 需要有关 React Js 的帮助

    我是 React Js 新手 我的代码无法正常工作 请看下面 这是我的脚本文件Main jsx 该文件由 React 编译 输出放置在 dist 文件夹下的 main js 文件中 var react require react react
  • Typescript 函数接口重载

    我有以下代码 interface MySecondInterface a type A interface MyInterface val1 string val2 string MySecondInterface a

随机推荐

  • 获取 Flask 中的当前用户 ID

    我对 Python 还很陌生 老实说 我对一般编程也很陌生 我目前正在制定一种待办事项列表 我需要它将待办事项放入适当的课程中 所有这些都与教育内容相关 所以 问题很简单 我将其作为 Flask 驱动的路线 app route add co
  • 方案单词列表 eq?

    我有一个问题 我需要查找列表是否等于第二个列表 例如 set eq 1 2 3 1 2 3 gt t set eq 1 2 3 2 3 4 gt f 这些例子在我的程序中是正确的 但这个例子不是 set eq quote quote one
  • 如何使用GridView从服务器获取JSON数据--Flutter

    我参考过食谱 https flutter dev docs cookbook networking fetch data https flutter dev docs cookbook networking fetch data 示例代码是
  • VueJS 自定义 Props 验证功能

    我是 VueJS 的新手 所以我一直在关注他们的官方指南 https v2 vuejs org v2 guide components html Prop Validation 我能够触发前 5 个属性验证器 但我似乎无法触发最后一个示例
  • 在 Firefox 中读取多行内容可编辑文本

    让我们读取一个 contenteditable 元素 span This is editable br Yes it is span 就在您在文本末尾手动添加两个空格之后 I get textContent gt This is edita
  • C++ 中的“new”运算符何时调用构造函数

    自从我开始学习 C 以来 我一直读到 new 运算符在返回指向分配内存的指针之前调用对象的构造函数 因此 出于好奇 我检查了 new 的源代码 并在以下位置找到了以下内容 GLIBCXX WEAK DEFINITION void opera
  • 使用一组字符而不是一个字符的序列对齐算法

    Summary 我从一些有关对齐算法的细节开始 最后我提出了我的问题 如果您了解对齐算法 请从头开始 考虑我们有两个字符串 例如 ACCGAATCGA ACCGGTATTAAC 有一些算法 例如 史密斯 沃特曼 https en wikip
  • R 绘图自定义数据格式变体

    我正在尝试访问customdata通过javascrit分配给每个数据点 例如为每个点分配一个超链接 然而 我注意到数据格式从一个图变为另一个图 这看起来很奇怪 这在本例中完美运行 基于this https stackoverflow co
  • WordPress:single.php 不显示 the_content()

    我正在创建一个自定义 WordPress 主题 但我似乎无法让 single php 模板正常工作 下面是我写的代码 标题出现了 但内容没有出现 有什么想法为什么不是吗 div div id post gt h2 a href title
  • 为什么要对 List< 进行泛型转换?将 Set..> 扩展为 List 在 Sun JDK 6 上成功,但在 Oracle JDK 7 上编译失败?

    下面的代码 class GenericCompilationFailureDemo List
  • 类型 IUserStore`1 没有可访问的构造函数

    我想使用 Unity 3 设置 MVC5 应用程序 我从标准模板创建了一个默认的 Web mvc5 应用程序 然后添加了 unity 当我访问 AccountController 中的注册操作时 出现以下异常 类型 IUserStore 1
  • 使用对象元素作为参数的 Firestore 查询

    我在项目中使用 Firestore 作为数据库 并且我有一个表 我需要在对象内执行查询 foo data bar data exObject dataToQuery value 这是一个结构示例 我想在对象内部进行查询 一个如下所示的查询
  • 具有定向光正交投影的 OpenGL 3+

    我目前遇到来自移动 类似太阳 光源的定向光阴影贴图的问题 当我最初实现时 光投影矩阵被计算为 3D 并且阴影贴图看起来很漂亮 然后我了解到 对于我想要做的事情 正交投影效果会更好 但我很难替换正确的投影矩阵 正如人们所期望的那样 每次滴答声
  • 包含 unistd.h 的 write() 包装例程会导致错误

    我正在编写一个包装例程write 要覆盖原始系统功能 并在其中我需要通过执行另一个程序execve 我为其添加了头文件unistd h 我收到错误conflicting types for write usr include unistd
  • 如何让Three.js全屏显示?

    我想用 Three js 制作游戏 但如何使其全屏显示 我看见本文 http learningthreejs com blog 2011 11 17 lets make a 3d game make it fullscreen 并且我在代码
  • Hibernate,更改标识符/主键

    当我尝试更改我的设置时 我收到以下异常 ID in an Entity identifier of an instance of com google search pagerank ItemEntity was altered from
  • 无法创建 Laravel 项目,因为缺少 mcrypt 扩展

    好吧 我看过很多关于这个问题的帖子 我花了一整天的时间来解决这个问题 但没有成功 我正在尝试创建一个 Laravel 项目 我使用的是 Mac Yosemite 运行 PHP 5 5 14 机器上还有旧版本的 PHP 当我尝试使用 lara
  • ionic 如何添加空白页面作为应用程序的主页?

    我想使用选项卡式菜单将新页面添加到默认离子应用程序中 并将此页面显示为应用程序的默认页面 我尝试这样做的方法如下 我在 app js 中添加了新状态 state home url home views home templateUrl te
  • 是否可以让Head JS的ready()函数等待两个脚本?

    我在网页上加载了三个脚本 我想在其中两个脚本完成加载后触发一个函数 head js webfont http ajax googleapis com ajax libs webfont 1 0 31 webfont js jquery ht
  • 如何缩小 SVG 元素联合的类型

    我正在使用 React 设置对 svg 元素的引用 该元素可能是