如何让 TypeScript 引擎在 JSX 中允许自定义 HTML 属性?

Posted

技术标签:

【中文标题】如何让 TypeScript 引擎在 JSX 中允许自定义 HTML 属性?【英文标题】:How do I get the TypeScript engine to allow custom HTML attributes in JSX? 【发布时间】:2018-07-26 20:30:34 【问题描述】:

我认为 Visual Studio Code 中的 TypeScript 引擎已收到更新,现在首次抱怨我在 html 元素上预先存在的自定义道具无效。这是一个没有 TypeScript 的 Babel/React/JSX 项目。

<div custom="bar" />

注意:它们(技术上)无效,但我使用它们,所以我知道我在做什么(这是故意的)。

See it on CodePen!

另见

How do I add attributes to existing HTML elements in TypeScript/JSX?(一年多以前我自己发的,现在已经失效了)。 JSX | Type Checking

【问题讨论】:

你可以使用data-属性,例如data-custom应该是有效的 请提供错误信息 【参考方案1】:

注意:如果一个属性名不是有效的JS标识符(如data-*属性),如果在元素属性类型中没有找到,则不认为是错误。

&lt;div data-custom="bar" /&gt;

https://www.typescriptlang.org/docs/handbook/jsx.html#attribute-type-checking https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/data-*

【讨论】:

在答案中添加详细信息 欢迎来到 Stack Overflow!请不要把你的源代码扔在这里。友善一点,并尝试对您的答案进行漂亮的描述,以便其他人会喜欢并支持它。见:How do I write a good answer?【参考方案2】:

React 类型定义文件(默认情况下 - index.d.tscreate-react-app 一起使用时)包含所有标准 HTML 元素的列表,以及已知属性。

为了允许自定义 HTML 属性,您需要定义它的类型。 通过扩展HTMLAttributes 接口来做到这一点:

declare module 'react' 
  interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> 
    // extends React's HTMLAttributes
    custom?: string;
  

【讨论】:

这会破坏“react”模块的 typescript 类型检查。【参考方案3】:

项目结构:

☁  extends-react-types  tree -I 'node_modules' 
.
├── App.tsx
├── index.d.ts
├── package-lock.json
├── package.json
└── tsconfig.json

0 directories, 5 files

包版本:


  "name": "extends-react-types",
  "devDependencies": 
    "@types/react": "^16.9.56",
    "typescript": "^4.3.5"
  ,
  "dependencies": 
    "react": "^16.8.6"
  

tsconfig.json:


    "compilerOptions": 
        "target": "es5",
        "lib": [
            "dom"
        ],
        "allowSyntheticDefaultImports": true,
        "moduleResolution": "Node",
        "jsx": "preserve",
    

App.tsx:

import React from 'react';

interface HomeProps extends React.ComponentPropsWithRef<'div'> 
export default function Home(props: HomeProps) 
  return (
    <div>
      <p _name="name" _error=true>
        123
      </p>
    </div>
  );

如您所见,p 元素中有两个自定义 HTML 属性:_name_error。现在,我们需要用这两个自定义 HTML 属性扩展ReactHTMLAttributes 接口。

选项 1:

index.d.ts:

import 'react';

declare module 'react' 
  interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> 
    _name?: string;
    _error?: boolean;
  

输出:

选项 2:

declare namespace React 
  interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> 
    _name?: string;
    _error?: boolean;
  

输出:

【讨论】:

以上是关于如何让 TypeScript 引擎在 JSX 中允许自定义 HTML 属性?的主要内容,如果未能解决你的问题,请参考以下文章

让 Vue.js 从带有 JSX 包的基本 CLI 安装使用 TypeScript 渲染 JSX

简单理解JavaScript,TypeScript和JSX

Vue TSX - 如何告诉 Typescript 在可重用组件中允许使用 HTML 属性?

如何在 TypeScript 中键入这个“as”JSX 属性?

如何在带有 React 的 Typescript/JSX 中使用带有箭头函数的泛型?

如何向 TypeScript/JSX 中的现有 HTML 元素添加属性?