gpt4 book ai didi

reactjs - mapStateToProps 可以缩小 props 的类型吗?

转载 作者:搜寻专家 更新时间:2023-10-30 20:58:20 25 4
gpt4 key购买 nike

我正在尝试向旧组件添加类型注释,但不确定是否 connect的类型支持我正在尝试做的事情。该组件是一个连接的组件,它接受一个广泛类型的 prop,然后使用该 prop 查找状态中的值,并吐出一个更窄的 prop。

目前,我可以用广泛的类型定义 Prop ,代码就可以工作了。但是,我在组件中编写的任何代码都必须符合这种广泛的类型,即使我知道它已经缩小了。因此,为了满足 typescript ,我要么必须添加类型断言,要么必须进行不必要的类型检查。

下面是一个简化的代码示例,用于显示该行为:

interface ExampleProps {
thing: string | number;
}

const Example extends React.Component<ExampleProps> {
render() {
const problem = this.props.thing * 2; // type error

// Workaround, but losing some typesafety
// const notAProblem = (this.props.thing as number) * 2;

// Workaround, but doing unnecessary checks
// if (typeof this.props.thing === 'number') {
// const notAProblem = this.props.thing * 2;
// }

return null;
}
}

const mapStateToProps = (state: RootState, otherProps: ExampleProps) => {
if (typeof otherProps.thing === 'string') {
return {
thing: state.lookup[otherProps.thing]; //resolves to a number
}
}
return {
thing, // also a number
}
}

export default connect(mapStateToProps)(Example)

在上面的代码中,typescript 正确地指出了 const problem: number = this.props.thing * 2;是个问题。使用我定义的类型,this.props.thing可能是一个字符串,所以它会正确给出错误 The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

是否可以使用 connect以不同的 Prop 进来而不是出去的方式?换句话说,我需要有人能够渲染 <Example thing={2} /><Example thing={"2"} /> ,但要让示例中的代码知道这一点,多亏了 mapStateToProps,thing只能是 number

最佳答案

方法 1:每个字段的通用类型

一种方法是使“事物”成为 ExampleProps 上的通用类型,即:

interface ExampleProps<T extends (string | number)> {
thing: T;
}

然后你可以分别在类和函数类型签名中指定不同的具体类型:

class Example extends Component<ExampleProps<number>> {
render() {
const problem: number = this.props.thing * 2;
return null;
}
}

const mapRootStateToExampleProps = (state: RootState, {thing}: ExampleProps<string | number>) => {
if (typeof thing === 'string') {
return {
thing: state.lookup[thing] //resolves to a number
}
}
return {
thing, // also a number
}
}

不过,这可能不是最佳解决方案,因为您的类型签名可能会很快变得冗长。它只对 ExampleProps 接口(interface)的一个或两个字段真正有意义。

方法 2:“out”参数的基础接口(interface),“in”参数扩展基础

另一种方法是声明一个表示传入 Prop 的基本接口(interface),然后声明一个扩展它的接口(interface)表示传出的 Prop - 然后您只需要指定在“传出”时修改的类型,这样您没有重复很多代码:

interface ExamplePropsIn {
thing: string | number;
other: string;
}

interface ExamplePropsOut extends ExamplePropsIn {
thing; number;
}

class Example extends Component<ExamplePropsOut> {
render() {
const problem: number = this.props.thing * 2;
return null;
}
}

const mapRootStateToExampleProps = (state: RootState, {thing}: ExamplePropsIn) => {
if (typeof thing === 'string') {
return {
thing: state.lookup[thing] //resolves to a number
}
}
return {
thing, // also a number
}
}

关于reactjs - mapStateToProps 可以缩小 props 的类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58241408/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com