根据已在对象中设置的属性缩小联合类型

Narrow a union type based on properties already set within an object

interface MockHTMLDivElement {
  divPropA: string,
  divPropB: string,
}

interface MockHTMLButtonElement {
  buttonPropA: string,
  buttonPropB: string,
}

type MockElement =
  | MockHTMLDivElement
  | MockHTMLButtonElement

const el: MockElement = {
  buttonPropA: 'foo', // implies that this is a MockHTMLButtonElement
  d // intellisense shows divPropA, divPropB here, even though buttonPropA is already 
    // present and implies this is a MockHTMLButtonElement and not a MockHTMLDivElement
}

Intellisense 仍会显示 divPropAdivPropB 作为该对象的可能属性,即使该对象已经具有 buttonPropA 属性,这意味着它是一个MockHTMLButtonElement.

有没有办法更好地键入它,以便 Intellisense 知道这是 MockHTMLButtonElementMockHTMLDivElement,并且只显示一种类型或另一种类型的属性,而不是显示两种类型的属性?

buttonPropA属性不是并集的判别式,因为这个属性的类型没有被MockHTMLDivElement类型禁止,所以{buttonPropA: 'foo', divPropA: 'bar', divPropB: 'baz'} 允许作为 MockHTMLDivElement.

类型的值

如果您改为使用有区别的联合,则只会建议来自一致分支的属性。在下面的示例中,kind 是判别式。

interface MockHTMLDivElement {
  kind: 'div',
  divPropA: string,
  divPropB: string,
}

interface MockHTMLButtonElement {
  kind: 'button',
  buttonPropA: string,
  buttonPropB: string,
}

type MockElement = MockHTMLDivElement | MockHTMLButtonElement

const el: MockElement = {
  kind: 'button',
  buttonPropA: 'foo',
  b, // suggestions include 'buttonPropB'
  d, // no suggestions
}

Playground Link