简体   繁体   English

当 Type B 以某种方式“扩展”Type A 时,如何停止 TypeScript 错误“Type A 没有与 Type B 相同的属性”

[英]How to stop TypeScript error 'Type A has no properties in common with Type B' when Type B "extends" Type A in some way

(edited Title to make more general) (编辑标题以使其更通用)

I'm working in a codebase which uses React class components and Typescript everywhere, and I'm trying to implement react-dropzone (a lightweight, simple but effective file-drop component) using the class-based method.我在一个代码库中工作,它到处都使用React类组件和Typescript ,我正在尝试使用基于类的方法实现react-dropzone (一个轻量级、简单但有效的文件放置组件)。 The Hooks implementation is cleaner and simpler but I'd prefer to avoid so as to preserve the paradigm maintained in the rest of the code. Hooks 实现更清晰、更简单,但我更愿意避免以保留在其余代码中维护的范式。

In all the README text for this module, it uses plain Javascript.在此模块的所有 README 文本中,它使用纯 Javascript。 Here's a typical example:下面是一个典型的例子:

import React from 'react'
import Dropzone from 'react-dropzone'

<Dropzone onDrop={acceptedFiles => console.log(acceptedFiles)}>
  {({getRootProps, getInputProps}) => (
    <section>
      <div {...getRootProps()}>
        <input {...getInputProps()} />
        <p>Drag 'n' drop some files here, or click to select files</p>
      </div>
    </section>
  )}
</Dropzone>

This seems a fairly unusual syntax anyway...无论如何,这似乎是一种相当不寻常的语法......

I've discovered that I can't just use this idiom unchanged in Typescript, so I am trying to get it to work using the following:我发现我不能在 Typescript 中使用这个习语不变,所以我试图使用以下方法让它工作:

import Dropzone, { DropzoneState } from "react-dropzone";

//...

export class BasicDropzone extends React.Component {
   onDrop = (files: Array<File>) => {
        console.log(files);
        this.files = files;
   }
//...
    render() {
//...
        return (
            <Dropzone onDrop={this.onDrop}>
                {(state: DropzoneState) => {
                    return (
                    <section className={styles.container}>
                        <div {...state.getRootProps({className: styles.dropzone})}>
                            <input {...state.getInputProps()} />
                         {/* ^^^^^ error here */}

                            <p>Drag and drop here, or click to select files</p>
                        </div>
                        <aside>
                            <h4>Files</h4>
                            <ul>{files}</ul>
                        </aside>
                    </section>
                )}}
            </Dropzone>
        );
    }
}

However the linter throws up the following error on the <input> tag: Type '{ refKey?: string | undefined; }' has no properties in common with type 'DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>'. ts(2559)然而, Type '{ refKey?: string | undefined; }' has no properties in common with type 'DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>'. ts(2559)<input>标签上抛出以下错误: Type '{ refKey?: string | undefined; }' has no properties in common with type 'DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>'. ts(2559) Type '{ refKey?: string | undefined; }' has no properties in common with type 'DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>'. ts(2559)

Just for further info, here are the Typescript definitions from the react-dropzone package of relevance:只是为了获得更多信息,这里是相关的react-dropzone包中的 Typescript 定义:

export type DropzoneState = DropzoneRef & {
  isFocused: boolean;
  isDragActive: boolean;
  isDragAccept: boolean;
  isDragReject: boolean;
  isFileDialogActive: boolean;
  draggedFiles: File[];
  acceptedFiles: File[];
  rejectedFiles: File[];
  rootRef: React.RefObject<HTMLElement>;
  inputRef: React.RefObject<HTMLInputElement>;
  getRootProps(props?: DropzoneRootProps): DropzoneRootProps;
  getInputProps(props?: DropzoneInputProps): DropzoneInputProps;
};

export interface DropzoneRef {
  open(): void;
}

export interface DropzoneRootProps extends React.HTMLAttributes<HTMLElement> {
  refKey?: string;
  [key: string]: any;
}

export interface DropzoneInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
  refKey?: string;
}

I'm really not sure how I can fix this - I'm relatively new to Typescript.我真的不确定如何解决这个问题 - 我对 Typescript 比较陌生。 Other Stackoverflow solutions come close but don't quite fit this issue.其他 Stackoverflow 解决方案接近但不太适合这个问题。

Thanks heaps in advance提前致谢

@zydnar: @zydnar:

{
  "compilerOptions": {
    "outDir": "build/dist",
    "module": "esnext",
    "target": "es5",
    "lib": ["es6", "dom"],
    "sourceMap": true,
    "allowJs": true,
    "jsx": "react",
    "moduleResolution": "node",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "suppressImplicitAnyIndexErrors": true,
    "experimentalDecorators": true,
    "esModuleInterop": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,

    // See https://github.com/rexxars/react-markdown/issues/207
    "allowSyntheticDefaultImports": true,

    // See https://stackoverflow.com/questions/52399839/typescript-duplicate-identifier-librarymanagedattributes
    // for the reason for this.
    "skipLibCheck": true,
    "baseUrl": "."
  },
  "exclude": [
    "node_modules",
    "build",
    "scripts/*.js",
    "acceptance-tests",
    "webpack",
    "jest",
    "src/setupTests.ts"
  ]
}

Also here's a complete example:这里还有一个完整的例子:

import React from "react";
import { observable, action } from 'mobx';
import { observer } from 'mobx-react';
import Dropzone, { DropzoneState } from "react-dropzone";

//const styles = require('./dropzone.css');

@observer
export class BasicDropzone extends React.Component {
    @observable files: Array<File> = [];
    @action onDrop = (files: Array<File>) => {
        console.log(files);
        this.files = files;
    }

    render() {
        const files = this.files.map((file: File) => (
            <li 
                key={file.name}
          >
            {file.name}
          </li>
        ));
        return (
            <Dropzone onDrop={this.onDrop}>
                {(state: DropzoneState) => (
                    <section className={"container"}>
                        <div {...state.getRootProps({className: "dropzone"})}>
                            <input {...state.getInputProps() } />
                            <p>Drag and drop here, or click to select files</p>
                        </div>
                        <aside>
                            <h4>Files</h4>
                            <ul>{files}</ul>
                        </aside>
                    </section>
                )}
            </Dropzone>
        );
    }

}

Thanks again再次感谢

我遇到了同样的问题,并且能够通过为<input/>元素提供typevalue来规避它,如评论中所述:

<input {...getInputProps()} type="file" value={files} />

暂无
暂无

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

相关问题 出现错误:类型“typeof B”不可分配给扩展 A 的 class B 的类型“typeof A” - Getting error: Type 'typeof B' is not assignable to type 'typeof A' for class B that extends A Typescript:a 类型的参数不能分配给 b 类型的参数 - Typescript: argument of type a is not assignable to parameter of type b Typescript 样式组件错误:“类型 '{ children: string; }' 没有与类型 'IntrinsicAttributes' 相同的属性。” - Typescript styled-component error: "Type '{ children: string; }' has no properties in common with type 'IntrinsicAttributes'." 类型 A 缺少类型 B 的以下属性:a、b - Type A is missing the following properties from type B: a, b TS function 的类型为 ( A | B ),具有单一返回类型 B。如何在不出现类型错误的情况下完成此操作? - TS function having types as ( A | B ), has single return type B. How do i accomplish this without getting type error? TypeScript:用于A类型的索引键和用于B类型的保留键 - TypeScript: indexed keys to type A and reserved keys to type B 类型中缺少类型 { 错误}<TYPE_A> , 但在类型上是必需的<TYPE_B> - Redux 特定问题 - Type { error } is missing in Type <TYPE_A>, but is required in type <TYPE_B> - Redux Specific Problem 类型'{孩子:元素; }' 与类型 'IntrinsicAttributes' 没有共同的属性 - React 18.2.0 - Type '{ children: Element; }' has no properties in common with type 'IntrinsicAttributes' - React 18.2.0 “数字”类型与“FindOneOptions”类型没有共同的属性<Client> &#39; - Type 'number' has no properties in common with type 'FindOneOptions<Client>' “string”类型与“clientStorageInterface”类型没有共同的属性 - Angular - Type 'string' has no properties in common with type 'clientStorageInterface' - Angular
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM