我想要一个在其根中可以包含字符串的对象,以及arrayValues对象中的字符串array.这是一个将在应用程序中使用的配置对象.

这个对象及其键将是动态的(通过用户状态值定义),因此我无法根据特定的键名指定类型.

我将从应用程序的一个部分向"ArrayValue"添加数组,从应用程序的另一个部分向"filters"添加字符串.

However I'm getting errors when accessing object properties:
TS PLAYGROUND

export type FiltersStateType = {
  filters:
    | {
        arrayValues: { // note: this should only appear once in filters object
          [key: string]: Array<string>
        }
      }
    | { [key: string]: string }
}

const example: FiltersStateType = {
  filters: {
    arrayValues: {
      sandwiches: ['ham', 'cheese'],
      milkshakes: ['choc', 'banana'],
    },
    randomString: 'hello',
  },
}

example.filters.arrayValues.sandwiches.filter((item: string) => item !== 'ham') 
// ❌ Property 'sandwiches' does not exist on type 'string | { [key: string]: string[]; }'.
// ❌ Property 'sandwiches' does not exist on type 'string'

const stringKey = 'milkshakes'
example.filters.arrayValues[stringKey].filter((item: string) => item !== 'choc') 
// ❌ Element implicitly has an 'any' type because expression of type '"milkshakes"' can't be used to index type 'string | { [key: string]: string[]; }'.
// ❌ Property 'milkshakes' does not exist on type 'string | { [key: string]: string[]; }'

example.filters.randomString = 'bye'
// ❌ Property 'randomString' does not exist on type '{ arrays: { [key: string]: string[]; }; } | { [key: string]: string; }'.
// ❌ Property 'randomString' does not exist on type '{ arrays: { [key: string]: string[]; }; }

我希望TypeScript能够理解这些对象中的类型,就像我在FiltersStateType中指定的那样.

你知道为什么会这样吗?

推荐答案

这是因为强调了unions :

export type FiltersStateType = {
  filters:
    | {
        arrayValues: {
          [key: string]: Array<string>
        }
      }
    | { [key: string]: string } // this one
// ---^^^^^^^^^^^^^^^^^^^^^^^^^---
}

正如您在联合体中指定的{ [key: string]: string },以下对象有效:

const example: FiltersStateType = {
  filters: {
    arrayValues: 'hello',
  },
}

TypeScript无法强制执行arrayValues键的值的形状,因为{ [key: string]: string }本身意味着任何键都可以有字符串的值.理想情况下,您必须更改类型定义的 struct ,如下所示:

// this is just an example, you should
// restructure as per your requirements 
type FiltersStateType = {
  filters: { [key: string]: string },
  arrayValues: { [key: string]: Array<string> }
}

Typescript相关问答推荐

我们过go 不能从TypeScript中的联合中同时访问所有属性?

类型脚本泛型最初推断然后设置

隐式键入脚本键映射使用

如果字符串文字类型是泛型类型,则用反引号将该类型括起来会中断

如何实现异构数组内函数的类型缩小

为什么Typescript不能推断类型?

以Angular 执行其他组件的函数

基元类型按引用传递的解决方法

->;Boolean类型的键不能分配给类型Never

创建依赖函数参数的类型

如何在不违反挂钩规则的情况下动态更改显示内容(带有状态)?

对于VUE3,错误XX不存在于从不存在的类型上意味着什么?

基于闭包类型缩小泛型类型脚本函数的范围

内联类型断言的工作原理类似于TypeScrip中的断言函数?

使用泛型以自引用方式静态键入记录的键

仅当定义了值时才按值筛选数组

当受其他参数限制时,通用参数类型不会缩小

如何强制对象数组中的对象属性具有非空字符串值?

如何在故事书的Typescript 中编写decorator ?

具有来自其他类型的修改键名称的 TypeScript 通用类型