首页 > 解决方案 > 打字稿将“父键”推断为类型

问题描述

如何将父级的键推断为嵌套属性的类型?


interface List {
    [key:string]: Definition<keyof List>
}

interface Definition<T> {
    [key:string]: Field<T>
}

type Field<T> = FieldA | FieldB<T>;

interface FieldA {
    type: string
}

interface FieldB<T> {
    definition: T 
}

const list:List = {
    def1: {
        field1: {
            type: 'a'
        }
    },
    def2: {
        definition: 'def1'
                    // ~~~ Type 'string' is not assignable to type 'Field<never>'.
    }

}

这里的definition属性类型是never。我想成为def1 | def2

或者更一般地获取父对象的键并将其用作类型。

游乐场链接

更简单的版本

interface List {
    [key:string]:keyof List
}

const list:List = {
    def1: 'def2',
          // ~~~ Type 'string' is not assignable to type 'never'.
    def2: 'def1'
          // ~~~ Type 'string' is not assignable to type 'never'.
}

为什么keyof List是类型never?考虑到我事先不知道钥匙,我怎么能拿到钥匙。

标签: typescripttype-inference

解决方案


这行得通,虽然它很丑;)

type List<K extends keyof any> = { [key in K]: K };

const list = new class C implements List<keyof C> {
    def1: 'def2'
    def2: 'def1'
    def5: 'def5'
}

这有点不那么难看,而且也有效;)

type List<T extends object> = { [key in keyof T]: keyof T }
const List = <O extends object>(o: List<O>): List<O> => o;

const list = List({
    def1: 'def2',
    def2: 'def1',
    def5: 'def5'
});

推荐阅读