有没有办法让hasOwnProperty做出类型检查?

时间:2018-01-07 06:50:43

标签: javascript typescript types

给出一些界面

interface Foo {
  foo?: string
}

有没有办法让hasOwnProperty检查属性对接口?

const f: Foo = { foo: 'a' }
f.hasOwnProperty('foo') // works fine
f.hasOwnProperty('fo')  // want this to throw error "fo" doesn't exist in Foo

我考虑过改为

f.foo !== undefined

但这并不完全等价,因为假设foo可能存在,但被分配给未定义的,即

const f: Foo = { foo: undefined }
f.hasOwnProperty('foo') // true
f.foo !== undefined     // false

我知道我可以编写自己的函数,用正确的类型签名包装hasOwnProperty,如has<T extends object>(obj: T, key: keyof T): boolean,但是想知道是否有更原生的替代品。

2 个答案:

答案 0 :(得分:-1)

obj.hasOwnProperty()检查它是否具有该属性,而不是属性的值,因此不需要进行类型检查。

我认为您需要重新考虑您的解决方案。如果您创建一个接口,您应该有明确定义的共享属性。如果你甚至不知道它将是什么类型,那么在界面中分享它们的重点是什么?

答案 1 :(得分:-1)

你在这里混合两种不同的东西。

TypeScript的类型系统仅在编译时存在,而hasOwnProperty()是运行时调用。

您通常不会在运行时获取类型信息,因为它只是JavaScript。

此外,您不应该进行此类测试,因为JavaScript(以及TypeScript)是动态类型的,这样可以进行鸭子输入。

考虑一下:

function doSomething(x: Foo) {
  // ...
}
let y = { foo: 'foo', fo: 'fo' }
doSomething(y)

在这种情况下,doSomething()是否会抛出错误?

在消费(doSomething())时,您只会关注您需要的内容,而不是强迫来电者仅传递您所需要的内容。

另一方面,TypeScript编译器确实知道拼写错误是常见问题,并且会使用以下代码抛出编译错误:

// Argument of type '{ fo: string; }' is not assignable to parameter of type 'Foo'.
// Object literal may only specify known properties, and 'fo' does not exist in type 'Foo'.
doSomething({ fo: 'foo' })

只有直接传入对象文字才会进行此检查。此代码不会触发错误:

let y = { fo: 'foo' }
doSomething(y)