Nimai
Nimai

Reputation: 783

How can I check that a string is a property a particular interface in TypeScript

I do have a real-world circumstance where I needed to refer to a property by name using a string literal. I wanted to make that type-safe, and it feels like in TypeScript, that should be possible. Consider the following simplified example:

interface MyInterface {
    foo: string,
}

const barName = <keyof MyInterface>'bar'    // No error?
const bazName = 'baz' as keyof MyInterface  // No error?
const bopName:keyof MyInterface = 'bop' // Finally, an error!

I believe the answer is that the <> and as operations in TypeScript are "type assertions" not "type cast attempts". The first two consts above are basically saying, "trust me, this is a key of MyInterface", while the third const is attempting a typed assignment, and failing.

I'd like to know if I'm right about that, and if so, if there's some other in-line way to test that a string literal is a keyof a given interface, without making a temp variable.

Upvotes: 3

Views: 1290

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249736

You are right about the reason you don't get an error on the first two const declarations.

The only way to get an error without an explicit type annotation on the variable it to use a helper function:

interface MyInterface {
    foo: string,
}
const key = <T>(o: keyof T) => o;
const barName = key<MyInterface>('bar')    // error
const fooName = key<MyInterface>('foo')    // ok

You could also leve the const declaration as is, the const will be typed as the string literal type associated with the string literal and you will get an error first time you use it to index into an instance of MyInterafce, although this might nto be applicable in all cases.

Upvotes: 3

Related Questions