在typescript中有没有一种方法可以声明类似“quot;嵌套对象“中的字符串”;?

在typescript中有没有一种方法可以声明类似“quot;嵌套对象“中的字符串”;?,typescript,Typescript,我有这个用例。我有一个生成的常量,它复制了JSON对象结构: 例如: JSON 生成常量: const MyConst = { first: 'first', second: { this: 'second.this', a: 'second.a', object: { and : 'second.object.and', } } } 它用于将对象映射到一个种类安全的结构,这样我就可以调用getInfoFrom

我有这个用例。我有一个生成的常量,它复制了JSON对象结构:

例如:

JSON

生成常量:

const MyConst = {
   first: 'first',
   second: {
      this: 'second.this',
      a: 'second.a',
      object: {
        and : 'second.object.and',
      }
   }
}

它用于将对象映射到一个种类安全的结构,这样我就可以调用
getInfoFromJson(MyConst.second.a)
,并将
complex
作为返回,当JSON数据(它是一个静态文件)获得更多密钥时,它会通过脚本进行更新

现在,
getInfoFromJson
的函数签名是

function getInfoFromJson(path: string): string {}
我想说的是“将任何字符串作为参数,只要它包含在MyConst中”


我还没有找到怎么做,我搜索的内容看起来不可能,但我想我可以试一试并在这里提问。

首先让我们假设
MyConst
的强类型足以让编译器知道它包含的确切字符串值。要做到这一点,最简单的方法是使用以下命令定义它:

如果检查其类型,您将看到:

/* const MyConst: {
    readonly first: "first";
    readonly second: {
        readonly this: "second.this";
        readonly a: "second.a";
        readonly object: {
            readonly and: "second.object.and";
        };
    };
} */

现在您需要一个名为
NestedValsMatching
的类型函数,其中给定类型
T
V
,您将得到
T
中所有值的并集,无论嵌套得有多深,匹配的
V
。因此理想情况下,
NestedValsMatching
将为您提供联合
“first”|“second.a”|“second.a”|“second.object.and”

NestedValsMatching
最直接的实现方式是递归的,而TypeScript目前不支持这种方式(请参阅)。编译器实际上不会抱怨它,但它确实会导致一些糟糕的性能和其他奇怪之处。在这里(但不要使用它)


/首先,让我们假设
MyConst
的强类型足以让编译器知道它包含的确切字符串值。要做到这一点,最简单的方法是使用以下命令定义它:

如果检查其类型,您将看到:

/* const MyConst: {
    readonly first: "first";
    readonly second: {
        readonly this: "second.this";
        readonly a: "second.a";
        readonly object: {
            readonly and: "second.object.and";
        };
    };
} */

现在您需要一个名为
NestedValsMatching
的类型函数,其中给定类型
T
V
,您将得到
T
中所有值的并集,无论嵌套得有多深,匹配的
V
。因此理想情况下,
NestedValsMatching
将为您提供联合
“first”|“second.a”|“second.a”|“second.object.and”

NestedValsMatching
最直接的实现方式是递归的,而TypeScript目前不支持这种方式(请参阅)。编译器实际上不会抱怨它,但它确实会导致一些糟糕的性能和其他奇怪之处。在这里(但不要使用它)


/假设我们能够构造如下类型:

类型对={
‘第一’:‘我只是第一’,
'第二,这个':'是',
“second.a”:“complex”,
'second.object.and':'里面可能有更多的对象'
}
在这种情况下,我们可以使用像
'second.a'
这样的字符串文本类型来查找字符串文本类型
'complex'

事实证明,您可以构造足够接近的对象,使其成为有用的
对。本质上,给定具有相同内部结构的两种类型
S
T
(即,它们具有相同的属性,如果这些属性的值是对象,则它们递归地具有相同的内部结构),我们希望将
S
的“叶”属性与
T
的“叶”属性配对

我的解决方案如下。正如@jcalz在他的回答中指出的,这是一个递归定义的映射类型,所以这里是龙

type Pairs=S扩展属性key?记录:{
[K in keyof S和keyof T]:成对
}[科学和技术的关键]
类型Lookup=P扩展记录?U:从来没有
键入PairsKeys

=P扩展记录?K:从来没有

Pairs
类型实际上构造了一个类似于
Record | Record |…
的联合类型,因此需要
查找
类型来执行从
second.a'
complex'
的实际映射。需要使用
PairsKeys
类型来构造键的类型,以便拒绝无效键。但它确实有效:

型式试验=成对
函数查找(键:K):查找{
抛出错误();//此处未实现
}
//推断出一种“情结”
设a=lookup('second.a');
//“second.b”上的类型错误
设b=lookup('second.b');
所有这些都说明了,既然反正生成了
MyConst
,也许您也有办法将原始
对作为常量生成?这似乎应该是一个更好的解决方案


假设我们能够构造如下类型:

类型对={
‘第一’:‘我只是第一’,
'第二,这个':'是',
“second.a”:“complex”,
'second.object.and':'里面可能有更多的对象'
}
在这种情况下,我们可以使用像
'second.a'
这样的字符串文本类型来查找字符串文本类型
'complex'

事实证明,您可以构造足够接近的对象,使其成为有用的
对。本质上,给定具有相同内部结构的两种类型
S
T
(即,它们具有相同的属性,如果这些属性的值是对象,则它们递归地具有相同的内部结构),我们希望将
S
的“叶”属性与
T
的“叶”属性配对

我的解决方案如下。正如@jcalz在他的回答中指出的,这是一个递归定义的映射类型,所以这里是龙

type Pairs=S扩展属性key?记录:{
[K in keyof S和keyof T]:成对
}[科学和技术的关键]
类型Lookup=P扩展记录?U:从来没有
键入PairsKeys

=P扩展记录?K:从来没有

Pairs
类型实际上构造了一个类似于
Record | Record |…
的联合类型,因此需要
Lookup
类型来执行
/* const MyConst: {
    readonly first: "first";
    readonly second: {
        readonly this: "second.this";
        readonly a: "second.a";
        readonly object: {
            readonly and: "second.object.and";
        };
    };
} */
// Suppose we are able to construct a type like this:

type Pairs = {
    'first': 'I am just first',
    'second.this': 'is',
    'second.a': 'complex',
    'second.object.and': 'It could have more objects inside'
}