![](/img/trans.png)
[英]Getting error: Type 'typeof B' is not assignable to type 'typeof A' for class B that extends A
[英]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/>
元素提供type
和value
来规避它,如评论中所述:
<input {...getInputProps()} type="file" value={files} />
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.