繁体   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

(编辑标题以使其更通用)

我在一个代码库中工作,它到处都使用React类组件和Typescript ,我正在尝试使用基于类的方法实现react-dropzone (一个轻量级、简单但有效的文件放置组件)。 Hooks 实现更清晰、更简单,但我更愿意避免以保留在其余代码中维护的范式。

在此模块的所有 README 文本中,它使用纯 Javascript。 下面是一个典型的例子:

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>

无论如何,这似乎是一种相当不寻常的语法......

我发现我不能在 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>
        );
    }
}

然而, 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)

只是为了获得更多信息,这里是相关的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;
}

我真的不确定如何解决这个问题 - 我对 Typescript 比较陌生。 其他 Stackoverflow 解决方案接近但不太适合这个问题。

提前致谢

@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"
  ]
}

这里还有一个完整的例子:

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>
        );
    }

}

再次感谢

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

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

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM