假设我正在构建一个可重用的库以用于React应用程序。该库将查找具有某些属性和值的某些DOM元素。
例如,它将查找具有“ foo”属性且可以等于“ bar”或“ baz”的DIV。
该库及其使用者均使用Typescript编写。
现在,当我尝试在用户代码中实例化DIV元素时:
// consumer/Consumer.tsx
import * as React from 'react';
import 'library';
export const Consumer = () =>
<div foo="bar">Hello</div>;
我收到类型错误
Type '{ children: string; type: string; onClick: () => void; foo: string; }' is not assignable to type 'DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>'.
Property 'foo' does not exist on type 'DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>'.ts(2322)
(property) JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
我可以通过在消费者的代码中添加merged a module declaration and interface declaration来解决此问题:
// consumer/Consumer.tsx
import * as React from 'react';
import 'library';
declare module 'react' {
interface HTMLAttributes<T> {
readonly foo?: 'bar' | 'baz';
}
}
export const Consumer = () =>
<div foo="bar">Hello</div>;
但是,我认为这确实应该在我的库的代码中完成,而不是在消费者的代码中完成。毕竟,定义合同是图书馆的工作,而不是消费者的工作。使用者应该能够导入库从库定义的任何接口。
因此,我尝试将声明移到我的库代码中。我不确定在哪里放置它,所以我决定将它附加到index.ts文件中,该文件将导出库的所有组件:
// library/src/index.ts
export * from './LibraryComponent1.tsx';
export * from './LibraryComponent2.tsx';
// added declaration here:
declare module 'react' {
interface HTMLAttributes<T> {
readonly foo?: 'bar' | 'baz';
}
}
不幸的是,这不起作用。当我重新编译该库并将其重新链接到我的使用者时,出现与上述相同的类型错误。
我尝试过:
declare namespace
代替declare module
export
前面添加interface HTMLAttributes
我在这里想念什么?有什么想法吗?
答案 0 :(得分:1)
首先,我本人不是TypeScript用户(尽管我在使用第三方软件包时已经对其进行了一些处理),因此,如果这个答案背叛了我对此领域的一些无知,我深表歉意。 / p>
您似乎想对图书馆承担不适当的责任。对我来说,您的库应该能够说出from django.contrib.auth.hashers import pbkdf2
import hashlib
from base64 import b64decode
identity_PasswordHash = "AOOVvPns8Nov6CsJDTAWz+QDOEO2csh60m5aYyX2Vn7LsNDhiiZ5UaSDWr5izwWeHA=="
pwd_plain = 'Hellow123';
def dotnet_identity_check_password(password, hash):
binsalt = b64decode(hash)[1:17]
binpwd = b64decode(hash)[17:]
genpwd = pbkdf2(password, binsalt, 1000, digest=hashlib.sha1, dklen=32)
if genpwd == binpwd:
return True
return False
if dotnet_identity_check_password(pwd_plain,identity_PasswordHash):
print("OK")
else:
print("Fail")
是该库的组件之一中div的有效属性,但是您似乎在暗示该库应该能够具有以下优点:更改不是由库的组件产生的元素的有效性的效果。
为确保区分清楚。对于我来说,该库看起来像是自然的(假设将应用适当的TypeScript来使其有效):
foo
,然后允许消费者毫无问题地使用// library code
export const LibComponent1 = (props) => {
return <div foo="bar">{props.children}</div>
}
。但是,允许更改库外部定义的组件中所有div的TypeScript验证以允许属性“ foo”似乎是不好的库行为。如果多个库执行此类操作,它们很容易彼此冲突或将问题隐藏在其他代码中。
答案 1 :(得分:-1)
假设您要在自定义组件中接受额外的属性,并使用传播运算符(例如...rest
)作为预先存在的属性。这是您的操作方式:
interface Props{
icon?: string;
}
type Button = Props & React.HTMLProps<HTMLButtonElement> & React.HTMLAttributes<HTMLButtonElement>;
function Button({
icon,
...rest
}: Button) {
return (
<button
{...rest}
>
{icon && <span>{icon}</span>}
{children}
</button>
}