允许类型化状态的临时空对象

Allow temporarily empty object for a typed state

我来自 JS 背景,现在正在学习 Typescript。我无法解决这个问题。 我有一个非常特殊类型的状态,我知道我将来需要使用它:

type NotificationValuesType = {
  channel: string
  for: NotificationUsageTypes
  id: string
  type: NotificationTypes
  workspace: string
}[]

我正在这样设置我的 React 状态:

  const [dropdownsState, setDropdownsState] = useState<NotificationValuesType>([])

问题是,最初我现在只能 typeid,当用户选择它们时,我可以通过一系列下拉菜单收集所有其他道具,事件触发,以及然后一次用一个下拉菜单填充状态,所以在某个时候,它只会是: [{id: "id", type: "type", channel: "channel"}] 在下一个事件中,它将是 [{id: "id", type: "type", channel: "channel", workspace: "workspace"}] 和一个更多的步骤和状态更新,以了解声明类型中的所有道具。

我不明白的是如何告诉 Typescript 停止对我大喊大叫,直到我知道所有的道具,并确保我将来会知道所有需要的道具。

感谢您阅读到最后! =)

I absolutely cannot make any of these props optional because they aren't optional.

也许不是在您完成时,而是在您构建它的过程中,如果值需要 undefined,则类型需要反映这一点。所以很可能你会想让状态变量有可选属性,然后你通过你的步骤来填写它,一旦你验证它就在那里你可以将它分配给一个类型的变量,其中属性是全部必填。

有一个名为 Partial 的辅助类型,它会接收一个类型并生成一个属性可选的新类型。

// Note: this type is just the individual object, not the array that you have
type Example = {
  channel: string
  for: NotificationUsageTypes
  id: string
  type: NotificationTypes
  workspace: string
}

const [dropdownsState, setDropdownsState] = useState<Partial<Example>[]>([])

// Later on, once you've verified that all the properties exist you can 
// assert that it's done. I don't know exactly what your verification 
// code will look like, but here's an example
if (dropdownsState.every(value => {
  return value.channel && value.for && value.id && value.type && value.workspace
})) {
  const finishedState = dropdownsState as Example[];
  // do something with the finished state
}

编辑:正如评论中指出的那样,如果您使用 type guard,则 typescript 可以缩小类型范围并避免您重新分配它:

if (dropdownsState.every((value): value is Example => {
  return value.channel && value.for && value.id && value.type && value.workspace
})) {
  // Inside this block, typescript knows that dropdownsState is an Example[]

}