Typescript 如何确保两个元素在一个对象中同时存在或根本不存在?

Typescript 如何确保两个元素在一个对象中同时存在或根本不存在?,typescript,Typescript,我遇到了一些答案,比如一个,但是我问题的措辞并没有返回相关的结果 考虑以下几点: type TNode = { data: { id: string; } | { tree: boolean; treeName: string; } } const nodes: TNode[] = [ { data: { id: '1', } }, {

我遇到了一些答案,比如一个,但是我问题的措辞并没有返回相关的结果

考虑以下几点:

type TNode = {
    data: {
        id: string;
    } | {
        tree: boolean;
        treeName: string;
    }

}

const nodes: TNode[] = [
    {
        data: {
            id: '1',
        }
    },
    {
        data: {
            id: '2',
        }
    },
    {
        data: {
            id: '3',
            tree: true,
            treeName: 'retrieval',
        }
    }
]
这种方法没有问题,但这不是我想要的。如果我从
节点
中的最后一个对象中删除属性
treeName:“retrieval”
,它应该会抱怨,说我包含了
,但我缺少
treeName

我怎样才能做到这一点

编辑 被接受的答案对我很有效,下面的方法也很有效,我最终使用了这种方法,因为我不想给我的对象添加额外的属性

interface INodeBase {
    id: string
}

interface INodeWithProps extends INodeBase {
    tree: boolean;
    treeName: string;
}

interface INodeWithOutProps extends INodeBase {
    tree?: never;
    treeName?: never;
}

type TNode = {
    data: INodeWithProps | INodeWithOutProps
}

const nodes: TNode[] = [
    {
        data: {
            id: '1',
        }
    },
    {
        data: {
            id: '2',
        }
    },
    {
        data: {
            id: '3',
            tree: true,
            treeName: 'retrieval',
        }
    },
    {
        data: {
            id: '4',
            tree: 'true', // error, 'treeName' is missing
        }
    },
]

让我们稍微简化一下示例:

type Node = Leaf | Tree;
type Leaf = {
  id: string
}
type Tree = {
  tree: boolean,
  treeName: string
}
然后,我们可以做:

const o = {
  id: '3',
  foo: 43,
  bar: false
}
const n: Node = o; // just fine: o has all properties a Leaf needs
特别要注意的是,我们通常可以提供任意的多余属性

如果多余的属性与联合中的其他类型匹配,也会发生同样的情况:

const o = {
  id: '3',
  tree: true,
}
const n: Node = o; // just fine: o has all properties a Leaf needs
TypeScript仅在少数特殊情况下执行多余的属性检查。最常见的是直接指定给对象类型的对象文字:

const o: Tree = {
  id: '3', // error: excess property not declared by Tree
  tree: true,
  treeName: 'retrieval',
}
有鉴于此,可以合理地预期,多余的属性检查也适用于联合类型:

const o: Node = {
  id: '3',
  tree: true,
  treeName: 'retrieval',
}
  
然而,这是,这不是你的

因此,您可能希望将定义更改为:

type Leaf = {
  id: string,
  tree: false,
}
type Tree = {
  tree: true,
  treeName: string
}
然后,
属性的值告诉TypeScript应该对哪个类型进行类型检查,同时允许在立即分配的对象文本中拒绝多余的属性:

const o: Node = {
  id: '3', // error: property id does not exist on Tree
  tree: true,
  treeName: 'retrieval'
}      

const q: Node = {
  tree: true,
  // error: property treeName is missing
}

const x: Node = {
  id: '4',
  tree: false,
  treeName: 'retrieval' // error: property treeName does not exist on Leaf
}

我对你的解释表示赞赏。亲切的问候。