从动态类型化对象中提取对象的键

时间:2018-10-25 16:12:15

标签: typescript

我有这个界面:

interface test {
   [key: string]: string
}

和该对象:

const obj: test ={
   name: 'mda',
   telephone: '1234'
}

现在,当我想在变量中使用此obj时,Intellisense不适用于该对象。换句话说,我可以选择一个对象中不存在的键。

const myName = obj.ndfnasdfn

并且编译器不显示此键的错误。 这是游乐场:playground

更新为嵌套对象: 对于此嵌套对象,什么是解决方案: 我在下面的嵌套对象中使用@Titian Cernicova-Dragomir solutin,但编译器未显示错误。

interface test {
[key: string]: string
 }

 function createTest<T extends test>(o: T) {
     return o;
 }
 interface state {
     test1: test,
     test2:test
 }
 const state: state = {
    test1:createTest({
        t1:'m',
        t2:'e'
  }),
  test2: createTest({
    t3:'sss'
     })
  }
 const {test1, test2} = state
 const t1 = test1.sdfsafsdf //no error

playground

更新2: 如果我们不使用createTest函数,那么我们就可以达到目的,因为我们没有指定要声明的类型playground

我的回答是,我使用type作为状态,并得到test1中不存在的键的编译器错误

1 个答案:

答案 0 :(得分:2)

如果您像以前一样显式指定变量的类型,它将是变量的最终类型,则编译器将推断出该变量的所有其他内容。

如果要让编译器推断类型,只需删除注释

const obj ={
   name: 'mda',
   telephone: '1234'
}

如果要将变量约束为仅包含字符串值,则将需要使用函数来约束类型,但让编译器仍可以推断类型:

interface test {
    [key: string]: string
}

function createTest<T extends test>(o: T) {
    return o;
}

const obj = createTest({
    name: 'mda',
    telephone: '1234'
    // age: 10 // error not a string
});
obj.name //ok
obj.sss //error

Playground link

对于嵌套样本,您将需要一个函数来创建state,而不仅仅是test。如果您明确指定test1的类型和test2的类型,无论返回的类型为createTest,它将是最终类型,则遵循相同的原则。

interface test {
    [key: string]: string
}

interface state {
    test1: test,
    test2:test
}
function createTest<T extends state>(o: T) {
    return o;
}
const state = createTest({
    test1: {
        t1: 'm',
        t2: 'e'
    },
    test2: {
        t3: 'sss'
    }
});
const {test1, test2} = state
const t1 = test1.sdfsafsdf //error

Playground link