简体   繁体   English

使用 Typescript 反应功能组件:Typescript 不理解更改属性类型

[英]React Functional component with Typescript: Typescript does not understand changing property types

I am passing a prop which can be string or an object to a react functional component, an example below.我将一个可以是字符串或 object 的道具传递给反应功能组件,例如下面的示例。 It works without typescript.它在没有 typescript 的情况下工作。 But, when I add typescript, it does not seem to understand that the prop (eg helpMessage below) can be either string or an object.但是,当我添加 typescript 时,它似乎不明白 prop(例如下面的 helpMessage)可以是字符串或 object。

I get this error TS2339: Property 'message' does not exist on type 'string | HelpMessage'. Property 'message' does not exist on type 'string'.我收到此错误TS2339: Property 'message' does not exist on type 'string | HelpMessage'. Property 'message' does not exist on type 'string'. TS2339: Property 'message' does not exist on type 'string | HelpMessage'. Property 'message' does not exist on type 'string'.

 import React, { FC } from 'react'; interface HelpMessage { headerText?: string; footerText?: string; message?: string; } interface FieldProps { name: string; helpMessage?: string | HelpMessage; } const ConditionalPropsComponent: FC<FieldProps> = ({ name, helpMessage }) => { const helpMessageIsString = typeof helpMessage === 'string'; const helpText = helpMessage && helpMessageIsString? helpMessage: helpMessage?.message; return ( <div> {helpText &&?helpMessageIsString && ( <div> <p>{helpMessage.?headerText}</p> <p>{helpMessage.?message}</p> <p>{helpMessage.;footerText}</p> </div> )} {helpText && helpMessageIsString && <p>{helpText}</p>} </div> ); }; export default ConditionalPropsComponent;

The error appears where the red wiggly lines are in the screenshot below:错误出现在下面屏幕截图中红色摆动线的位置:

在此处输入图像描述

I created a code sandbox, so that you can see the issue.我创建了一个代码沙箱,以便您可以看到问题。 https://codesandbox.io/s/github/nfabacus/React-typescript-dynamic-type-issue/tree/main/?file=/src/index.tsx:217-226 https://codesandbox.io/s/github/nfabacus/React-typescript-dynamic-type-issue/tree/main/?file=/src/index.tsx:217-226

Basically, extracting the condition to const helpMessageIsString = typeof helpMessage === 'string';基本上,将条件提取到const helpMessageIsString = typeof helpMessage === 'string'; throws the type error, but if I replace every one of them with typeof helpMessage === 'string' , error disappears, but this is repetitive..抛出类型错误,但如果我用typeof helpMessage === 'string'替换它们中的每一个,错误就会消失,但这是重复的..

also, below works but feels hacky - helpMessage is either HelpMessage or undefined.此外,下面的作品但感觉很hacky - helpMessage 是HelpMessage 或未定义。 When I pass string, it is neither the HelpMessage object or undefined, but typescript does not complain..which is strange.当我传递字符串时,它既不是 HelpMessage object 也不是未定义,但 typescript 没有抱怨......这很奇怪。

interface HelpMessage {
  headerText?: string;
  footerText?: string;
  message?: string;
}

interface FieldProps {
  name: string;
  helpMessage?: HelpMessage;
}

const ConditionalPropsComponent: React.FC<FieldProps> = ({
  name,
  helpMessage
}) => {
  const helpMessageIsString = typeof helpMessage === 'string';
  const helpText = helpMessageIsString ? helpMessage : helpMessage?.message;
....

Typescript is great, but in this particular case, I feel a bit disappointed with Typescript, if there is not a good solution for this... Typescript很棒,但是在这种特殊情况下,我对Typescript感到有些失望,如果没有好的解决方案...

What you lack in this example is Type Assertion and Type Inference .您在此示例中缺少的是Type AssertionType Inference

Typescript is a compiler, it can't interrupt types in run time. Typescript 是一个编译器,它不能在运行时中断类型。

When you writing such code, Typescript deduce helpMessageIsString type as boolean and not as "if its a truthy boolean so helpMessage is string".当您编写此类代码时,Typescript helpMessageIsString类型推断为boolean而不是“如果它是真实的 boolean 所以helpMessage是字符串”。

// helpMessageIsString is boolean
const helpMessageIsString = typeof helpMessage === "string";

// Typescript can't interrupt if the boolean has a meaning for true
//                                      v string | HelpMessage
const helpText = helpMessageIsString ? helpMessage : helpMessage?.message;

The most simple way to make it work, is using Type Inference by condition blocks:使其工作的最简单方法是通过条件块使用类型推断:

if (typeof helpMessage === "string") {
  // In this scope, helpMessage is a STRING
} else {
  // In this scope, helpMessage is of type HelpMessage
}

For other unreadable solutions, just pick one of available APIs in type assertion docs.对于其他不可读的解决方案,只需在类型断言文档中选择一个可用的 API。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 打字稿React:访问组件属性类型 - Typescript React: Access component property types <a>使用 onClick 和 TypeScript</a>响应功能<a>组件</a> - React functional <a> component with onClick and TypeScript TypeScript 中的 React PrivateRoute 功能组件 - React PrivateRoute functional component in TypeScript 在 Typescript 中重写为 React 功能组件时出错:属性“forceUpdateHandler”在类型“MutableRefObject”上不存在<spinner | null> '</spinner> - Error rewriting as a React Functional Component in Typescript: Property 'forceUpdateHandler' does not exist on type 'MutableRefObject<Spinner | null>' React - useRef 与 TypeScript 和功能组件 - React - useRef with TypeScript and functional component React Class 组件属性中的 TypeScript 错误在类型“Readonly&lt;{}&gt;”上不存在,不确定如何为 state 设置类型 - TypeScript errors in React Class Component property does not exist on type 'Readonly<{}>', not sure how to set types for state 无法更新反应打字稿功能组件中的上下文 - cannot update context in react typescript functional component 将 function 作为道具传递给 Typescript 反应功能组件 - Passing a function as a prop to a Typescript React Functional Component 使用 typescript 键入功能组件 - Typing a functional component react using typescript 在 React 功能组件 state 和 Typescript 中嵌套了 object - Nested object in React functional component state with Typescript
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM