keyof Foo vs Object.keys(Foo)

时间:2017-01-03 14:10:15

标签: typescript typescript-typings

任何人都可以解释为什么:

let foo = new Foo(),
    x: (keyof Foo)[] = Object.keys(foo)

导致:

  

输入' string []'不能指定类型'""" | " BAR1" ...'

(使用tsc 2.1.4)

3 个答案:

答案 0 :(得分:1)

我认为这是因为keyof运算符在类型声明空间中运行,而Object.keys则返回来自变量声明空间的变量。而你不能简单地将不同空间的值分配给彼此。

有关此事的更多信息:spaces

答案 1 :(得分:1)

你可以输入断言然后它没关系:

class Foo {
    x: number;
    y: number;
}

type Keys = keyof Foo;

let foo = new Foo(),
    x = Object.keys(foo) as Keys[];

code in playground

问题在于您尝试将string[]放入(在我的示例中)('x' | 'y')[]更具体。 这也会发生在这里:

interface A {
    x: number;
}

interface B extends A {
    y: number;
}

let a: A = { x: 5 };
let b1: B = a; // error
let b2: B = a as B; // fine

如果您想将某些内容转换为更具体的类型,那么您需要告诉编译器您通过类型断言来了解您正在做的事情。

答案 2 :(得分:0)

方法Object.keys(...)返回一个字符串数组:

class Foo {
    public foo: string;
    public bar: string;
}

let foo = new Foo(),
    x: string[] = Object.keys(foo)

TypeScript没有完全评估Object.keys的结果是什么,以保证值是正确的...虽然你可以看到它们在这个例子中是兼容的...... / p>

type example = keyof Foo; // "foo", "bar"

因此,您的类型注释在原始示例中是正确的,但TypeScript没有为Object.keys结果提供这样的特定类型。