【问题标题】:TypeScript cannot assign to optional property "is not assignable to type undefined"TypeScript 无法分配给可选属性“不可分配给未定义的类型”
【发布时间】:2021-09-03 01:34:55
【问题描述】:

这里是重现问题的最少代码:

const map = {
  FOO: 'foo',
  BAR: 'bar',
} as const

export const CSV_COLUMNS_ALL = Object.values(map)

export type ColumnName = typeof CSV_COLUMNS_ALL[number]

export type RowField<CN extends ColumnName> = {
  /** The Original value from the CSV file */
  original: string
  /** The row index for the csv row that this field belongs to */
  rowIndex: number
  /** The header text in the CSV for this column of data */
  columnName: CN
}

export type CsvRow = {
  [k in ColumnName]?: RowField<k>
} & {
  index: number
}

const row:CsvRow = CSV_COLUMNS_ALL.reduce((row, columnName) => {
  row[columnName] = { columnName, original: '', rowIndex: 1 }
  return row
}, { index: 1 } as CsvRow)

Playground here

有问题的行是这一行:

row[columnName] = { columnName, original: '', rowIndex: 1 }

它基本上告诉我我不能将此值分配给类型“未定义”

但是,rowCsvRow 类型,columnNameColumnName 类型,这应该是一个可分配的属性,具有可选的 RowField&lt;ColumnName&gt; 类型,这满足了。

那么为什么它阻止了我,我该如何解决?

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    还不能解决问题,但我有一个建议,可以用另一种方法来做这件事,这似乎与 typescript 配合得很好:

    row = {...row, [columnName]: { columnName, original: '', rowIndex: 1 }}
    

    基本传播row参数对象并添加新属性。全部保存在row参数中。

    查看playground

    【讨论】:

    • 是的,我认为问题在于,当我启动 reduce 函数时,使用 { index: 1 } as CsvRow 它锁定了未定义的通用参数,所以我不能再分配给它。我认为解决方法可能是重置通用参数的最佳方法。
    【解决方案2】:

    另一个建议是取消 RowField 类型,这会使错误消失,请查看 playground

    const map = {
      FOO: 'foo',
      BAR: 'bar',
    } as const
    
    export const CSV_COLUMNS_ALL = Object.values(map)
    
    export type ColumnName = typeof CSV_COLUMNS_ALL[number]
    
    export type RowField = {
      /** The Original value from the CSV file */
      original: string
      /** The row index for the csv row that this field belongs to */
      rowIndex: number
      /** The header text in the CSV for this column of data */
      columnName: ColumnName
    }
    
    export type CsvRow = {
      [k in ColumnName]?: RowField
    } & {
      index: number
    }
    
    const row:CsvRow = CSV_COLUMNS_ALL.reduce((row, columnName) => {
      row[columnName] = { columnName, original: '', rowIndex: 1 } ;
    return row
    }, { index: 1 } as CsvRow)
    

    无法弄清楚发生这种情况的原因,发现另一个类似的question 表明属性冲突。也许更有经验的开发人员可以解释这里发生了什么。

    【讨论】:

      猜你喜欢
      • 2018-06-24
      • 2021-02-28
      • 2018-03-29
      • 2021-07-02
      • 1970-01-01
      • 1970-01-01
      • 2022-08-23
      • 2021-04-29
      • 2022-01-07
      相关资源
      最近更新 更多