微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

对象的递归类型迭代没有正确地将键与 Typescript 中的值关联起来

如何解决对象的递归类型迭代没有正确地将键与 Typescript 中的值关联起来

我正在尝试定义一个 TypeScript 类型,该类型匹配字符串,这些字符串用作类似于严格类型对象上的 JsonPath 的访问器。所以对于类型为

的对象
{ root: { inner: { child: string } } } 

字符串 $root.inner.child 应为有效类型,但 $root.something.else 不应为有效类型。

这是我目前得到的 (Typescript Playground):

type PropertyAccessor<Properties,Prefix extends string = ''> =
  Properties extends Primitive
    ? Prefix : (
      Properties extends { [Key in keyof Properties]: infer Value }
        ? PropertyAccessor<Value,`${Prefix}${Prefix extends '' ? '$' : '.'}${StringOrNever<keyof Properties>}`>
        : never
      );

// Helper types
type StringOrNever<T> = T extends string ? T : never;
type Primitive = string | number | boolean | bigint | symbol | null | undefined;

它几乎可以工作。查看以下示例时:

const example = {
    root1: {
        sub1: {
            subSub1: {
                subSubSub1: 'value'
            }
        },sub2: {
            subSub2: {
                subSubSub2: 'value'
            }
        },}
}

// Works as intended
const accessor1: PropertyAccessor<typeof example> = '$root1.sub1.subSub1.subSubSub1'; 

// Should throw an type error,but does not!
const accessor2: PropertyAccessor<typeof example> = '$root1.sub2.subSub1.subSubSub1';

// Correctly throws type error
const accessor3: PropertyAccessor<typeof example> = '$root1.sub1.subSub2.subSubSub1';

// Correctly throws type error
const accessor4: PropertyAccessor<typeof example> = '$root1.sub1.subSub1.subSubSub2';

它适用于某些字符串,但不是全部。我认为问题在于,通过将对象类型解构为 keyof Properties 作为 Key 和 Value = Properties[keyof Properties],我会得到类似 Key = 'sub1' | 'sub2'Value = { subSub1: ... } | { subSub2: ... } 的东西,所以单个键不是与它们各自的值正确关联。但是,示例 accessor3accessor4 正确抛出类型错误这一事实让我希望它应该以某种方式可行。

有人知道我如何调整类型,以便为 accessor2 抛出类型错误,而 accessor1 不会抛出类型错误吗?`

整个代码可用作 Typescript Playground

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。