如何使用typescript中的已知类型为1个已知属性和未知属性名建模

如何使用typescript中的已知类型为1个已知属性和未知属性名建模,typescript,Typescript,我如何建模1个已知属性和1个我知道类型但不知道属性名称的属性 我认为它应该是一个递归类型,但我不完全确定如何在typescript中做到这一点 所以我有这种安排: export const hierarchy: Hierarchy = { location: { name: "location", regions: [ { name: "West Coast", states: [ { n

我如何建模1个已知属性和1个我知道类型但不知道属性名称的属性

我认为它应该是一个递归类型,但我不完全确定如何在typescript中做到这一点

所以我有这种安排:

export const hierarchy: Hierarchy = {
  location: {
    name: "location",
    regions: [
      {
        name: "West Coast",
        states: [
          {
            name: "California",
            cities: [
              { name: "San Diego", sites: [{name: "site 1"},
              { name: "Los Angeles" },
              { name: "San Jose" },
            ],
          },
        ],
      }
    ],
  },
};
因此,每个对象都有一个名称字段和一个相同类型、任意深度的数组

以下是我天真的尝试,显然不起作用:

export interface Graph<T> {
  name: string;
  [key: string]: Graph[]
}
导出接口图{
名称:字符串;
[键:字符串]:图形[]
}

TypeScript目前根本无法将“除
'name'
之外的所有
字符串”作为类型,更不用说作为类型或映射类型了。所以你想说:

// this is not valid TypeScript (yet?)
interface Graph { 
  name: string, 
  [k: string & not "name"]: Array<Graph> 
}
这就是它的工作原理:

// okay
const hierarchy = asHierarchy({
    location: {
        name: "location",
        regions: [
            {
                name: "West Coast",
                states: [
                    {
                        name: "California",
                        cities: [
                            {
                                name: "San Diego",
                                sites: [
                                    { name: "site 1" },
                                    { name: "Los Angeles" },
                                    { name: "San Jose" },
                                ],
                            },
                        ],
                    }
                ],
            },
        ]
    }
});
以下是一些错误:

const badHierarchy1 = asHierarchy({
    location: {
        name: "Okay",
        notAnArray: 123 // error!
//      ~~~~~~~~~~ <-- Type 'number' is not assignable to type '{ name: string; }[]'.    
    }
})

const badHierarchy2 = asHierarchy({
    location: { // error!
//  ~~~~~~~~ <-- Property 'name' is missing in type '{ noName: never[]; }'
        noName: []
    }
})

const badHierarchy3 = asHierarchy({
    location: {
        name: "level1",
        stuff: [
            {
                name: "level2",
                deeperNotAnArray: "oopsie"; // error!
//              ~~~~~~~~~~~~~~~~ <--
// Type 'string' is not assignable to type '{ name: string; }[]'.
            }
        ]
    }
})
相反。每个有效的
T&Graph
都可分配给
LooseGraph
,但反之亦然,因此您可能需要在库中执行一些断言。但这是我认为你目前能用TypeScript做的最好的了


好吧,希望这会有帮助;祝你好运

TypeScript目前根本无法将“除
'name'
之外的所有
字符串
作为类型,更不用说作为类型或映射类型了。所以你想说:

// this is not valid TypeScript (yet?)
interface Graph { 
  name: string, 
  [k: string & not "name"]: Array<Graph> 
}
这就是它的工作原理:

// okay
const hierarchy = asHierarchy({
    location: {
        name: "location",
        regions: [
            {
                name: "West Coast",
                states: [
                    {
                        name: "California",
                        cities: [
                            {
                                name: "San Diego",
                                sites: [
                                    { name: "site 1" },
                                    { name: "Los Angeles" },
                                    { name: "San Jose" },
                                ],
                            },
                        ],
                    }
                ],
            },
        ]
    }
});
以下是一些错误:

const badHierarchy1 = asHierarchy({
    location: {
        name: "Okay",
        notAnArray: 123 // error!
//      ~~~~~~~~~~ <-- Type 'number' is not assignable to type '{ name: string; }[]'.    
    }
})

const badHierarchy2 = asHierarchy({
    location: { // error!
//  ~~~~~~~~ <-- Property 'name' is missing in type '{ noName: never[]; }'
        noName: []
    }
})

const badHierarchy3 = asHierarchy({
    location: {
        name: "level1",
        stuff: [
            {
                name: "level2",
                deeperNotAnArray: "oopsie"; // error!
//              ~~~~~~~~~~~~~~~~ <--
// Type 'string' is not assignable to type '{ name: string; }[]'.
            }
        ]
    }
})
相反。每个有效的
T&Graph
都可分配给
LooseGraph
,但反之亦然,因此您可能需要在库中执行一些断言。但这是我认为你目前能用TypeScript做的最好的了


好吧,希望这会有帮助;祝你好运

没有办法做到这一点,因为
key
可能是
“name”
。我不能使用exclude?TypeScript不支持“除一个以外的所有可能字符串”这样的类型。没有办法做到这一点,因为
key
可能是
“name”
。我不能使用exclude?TypeScript不支持类似的类型“所有可能的字符串,除了一个”。