如何为 TypeScript React 应用程序设置键/值默认状态

Posted

技术标签:

【中文标题】如何为 TypeScript React 应用程序设置键/值默认状态【英文标题】:How to set key/value default state for TypeScript React app 【发布时间】:2020-09-20 04:44:32 【问题描述】:

我必须将 React 应用程序转换为 Typescript,但我无法确定属性设置散列对象的初始状态。

原版js

export default class Wizard extends PureComponent 
    constructor(props) 
        super(props);

        this.state = this.initialState();
    



    /** Setup Steps */
    initialState = () => 
        const state = 
            activeStep: 0,
            hashKeys: ,
        ;

        // Set initial classes
        // Get hash only in client side
        const hash = typeof window === 'object' ? this.getHash() : '';
        const children = React.Children.toArray(this.getSteps());
        children.forEach((child, i) => 
            // Create hashKey map
            state.hashKeys[i] = (child.props && child.props.hashKey) || `step$i + 1`;
            state.hashKeys[state.hashKeys[i]] = i;
        );

        ...

        return state;
    
...

我的失败尝试

export interface TState 
  activeStep?: number
  hashKeys: 
    [key: number]: string
  


export default class StepWizard extends PureComponent<,TState> 
   constructor(props: IStepWizardProps) 
       super(props)
       this.state = this.initialState()
   

   initialState = () => 
    const state = 
      activeStep: 0,
      hashKeys: ,  /* <---- This seems to be the problem */
    

    // Set initial classes
    // Get hash only in client side
    const hash = typeof window === "object" ? this.getHash() : ""

    const children = React.Children.toArray(this.getSteps())
    children.forEach((child, i) => 
      // Create hashKey map
      // the following give a TS error
      // ERROR: (property) hashKeys: 
      //           Element implicitly has an 'any' type because expression of type 'number' 
      //           can't be used to index type ''.
      //        No index signature with a parameter of type 'number' was found on type ''.ts(7053)
      state.hashKeys[i] = (child.props && child.props.hashKey) || `step$i + 1`
      state.hashKeys[state.hashKeys[i]] = i
    )

   ...

我得到state.hasKeys[i](属性)hashKeys: 元素隐式具有“任何”类型,因为“数字”类型的表达式不能用于索引类型“”。 在类型“”.ts(7053)

上找不到带有“数字”类型参数的索引签名

【问题讨论】:

【参考方案1】:

问题似乎来自于 hashKeys 的定义为

Typescript 不知道键/值的数据类型,但是,你可以告诉它!

const hashKeys =  as Record<number, string>;

const x = hashKeys[0];

你的例子:

        const state = 
            activeStep: 0,
            hashKeys:  as Record<string, string>, // or whatever your types are
        ;

【讨论】:

const state: TState = activeStep: 0, hashKeys: 也可以吗? @Thankyou Indeed it would! 非常感谢。我从你的 TS 答案中学到了很多:D【参考方案2】:

选项 1:Type Union

export interface TState 
  activeStep?: number;
  hashKeys: 
    [key: number]: string
   | ;

此语法表明hashKeys 可以采用[key: number]: string 的形式。

如果您想提高该联合的可读性,您可以这样做:

type HashMap = 
  [key: number]: string;


export interface TState 
  activeStep?: number;
  hashKeys: HashMap | ;

选项 2:Partial(pssst 可能不是最佳的 - 请参阅选项 3)

Partial 构造了一个所有属性都设置为可选的类型,这意味着 通过具有不存在的键和值属性来符合定义。

type HashMap = 
  [key: number]: string;


export interface TState 
  activeStep?: number;
  hashKeys: Partial<HashMap>

选项 3:Type assertion

As pointed out in this answer,这种方法更好地实现了“正确性和生产力之间的平衡”。

type HashMap = 
  [key: number]: string;


export interface TState 
  activeStep?: number;
  hashKeys: HashMap;


//

const state = 
  activeStep: 0,
  hashKeys:  as HashMap,
;

【讨论】:

以上是关于如何为 TypeScript React 应用程序设置键/值默认状态的主要内容,如果未能解决你的问题,请参考以下文章

如何为 React Native 嵌套组件创建 Typescript 定义

如何为无状态 React 组件创建 TypeScript 类型定义?

如何为 useReducer 键入 state 和 dispatch - typescript 和 react

如何为 React Action Hook Store 定义 Typescript 属性和类型

如何为 React TypeScript 组件上的 props 设置默认值?

如何为 TypeScript 定义文件导入文件