【问题标题】:How to set key/value default state for TypeScript React app如何为 TypeScript React 应用程序设置键/值默认状态
【发布时间】: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)

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

【问题讨论】:

    标签: reactjs typescript


    【解决方案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,
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-26
      • 2020-02-09
      • 1970-01-01
      • 2022-10-06
      • 1970-01-01
      • 2021-10-07
      • 1970-01-01
      • 2014-06-01
      相关资源
      最近更新 更多