Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
键入泛型typescript结构时出现问题_Typescript - Fatal编程技术网

键入泛型typescript结构时出现问题

键入泛型typescript结构时出现问题,typescript,Typescript,我想处理以下数据: const stateTest = { natures : { nature1: { amounts: { column1: 10, column2: 10, }, natureDetails : { detail1 : { amounts: { column1: 10, column2: 10,

我想处理以下数据:

const stateTest  = {
  natures : {
    nature1: {
      amounts: {
        column1: 10,
        column2: 10,
      },
      natureDetails : {
        detail1 : {
          amounts: {
            column1: 10,
            column2: 10,
          },
          descriptionShown: false
        }
      }
    }
  }
}
其中列列表(此处为column1,column2)是一个参数

因此,我声明了以下类型和接口

type State<T extends GenericColumnList> = T & {
  natures: naturesSet<T>
}
type GenericColumnList = Record<string, number>
type naturesSet<T extends GenericColumnList> = Partial<Record<string, RowNature<T>>>
export interface RowNature<T extends GenericColumnList> {
  natureDetails: NatureDetailsSet<T>
  amounts: T
}
type NatureDetailsSet<T> = Partial<Record<string, RowDetailNature<T>>>
export interface RowDetailNature<T> {
  amounts: T
  descriptionShown: boolean
}
即:

const stateTest: State<MyColumns>  = {
  natures : {
    nature1: {
      amounts: {
        column1: 10,
        column2: 10,
      },
      natureDetails : {
        detail1 : {
          montants: {
            column1: 10,
            column2: 10,
          },
          descriptionShown: false
        }
      }
    }
  }
}
const stateTest:状态={
性质:{
性质1:{
金额:{
专栏1:10,
专栏2:10,
},
性质详情:{
详情1:{
蒙塔人:{
专栏1:10,
专栏2:10,
},
描述显示:false
}
}
}
}
}
typescript编译器抱怨说

“MyColumns类型不符合记录”,我不明白为什么。

类型
记录
有一个字符串。
接口
MyColumns
没有索引签名,因此类型不兼容


有这样一个概念,即没有显式索引签名的类型被视为与可索引类型兼容,只要所有已知属性都符合索引签名。。。但这不适用于声明为
接口的类型
;它仅适用于匿名类型(或此类匿名类型的别名)。GitHub中有一个公开的问题,正在讨论这个问题。事实证明,就目前而言,这种行为是不正确的

因此,处理此问题的一种方法是将
MyColumns
设置为匿名类型的类型别名,而不是任何接口,如下所示:

export type MyColumns = {
  column1?: number
  column2?: number
}
然后,您需要在
GenericColumnList
的域中包含
undefined
,因为
MyColumns['column1']
的类型是
number | undefined
,而不仅仅是
number
(假设我们使用的是推荐的
--严格的
编译器选项包括):

在这里,我们将属性设置为可选(
),原因与前面添加的
| undefined
相同:使可选/缺少的键在存在
--stricnullchecks
的情况下兼容

这需要在代码周围撒一些

type State<T extends GenericColumnList<T>> = T & {
  natures: NaturesSet<T>
}
type NaturesSet<T extends GenericColumnList<T>> = Partial<Record<string, RowNature<T>>>
export interface RowNature<T extends GenericColumnList<T>> {
  natureDetails: NatureDetailsSet<T>
  amounts: T
}
type State=T&{
自然:自然集
}
类型属性set=Partial
导出接口RowNature{
natureDetails:NatureDetailsSet
金额:T
}
同样,您的任务将有效:

const stateTest: State<MyColumns> = {
  natures: {
    nature1: {
      amounts: {
        column1: 10,
        column2: 10,
      },
      natureDetails: {
        detail1: {
          amounts: {
            column1: 10,
            column2: 10,
          },
          descriptionShown: false
        }
      }
    }
  }
}; // okay
const stateTest:状态={
性质:{
性质1:{
金额:{
专栏1:10,
专栏2:10,
},
性质详情:{
详情1:{
金额:{
专栏1:10,
专栏2:10,
},
描述显示:false
}
}
}
}
}; // 可以


大概是
montants
是个打字错误吗?好家伙++++
const stateTest: State<MyColumns> = {
  natures: {
    nature1: {
      amounts: {
        column1: 10,
        column2: 10,
      },
      natureDetails: {
        detail1: {
          amounts: {
            column1: 10,
            column2: 10,
          },
          descriptionShown: false
        }
      }
    }
  }
}; // okay
type GenericColumnList<T> = { [K in keyof T]?: number } 
type State<T extends GenericColumnList<T>> = T & {
  natures: NaturesSet<T>
}
type NaturesSet<T extends GenericColumnList<T>> = Partial<Record<string, RowNature<T>>>
export interface RowNature<T extends GenericColumnList<T>> {
  natureDetails: NatureDetailsSet<T>
  amounts: T
}
const stateTest: State<MyColumns> = {
  natures: {
    nature1: {
      amounts: {
        column1: 10,
        column2: 10,
      },
      natureDetails: {
        detail1: {
          amounts: {
            column1: 10,
            column2: 10,
          },
          descriptionShown: false
        }
      }
    }
  }
}; // okay