Reputation: 387
As far as we know typescript allow us to declare partially types but what when we gonna to check if my property is in keyof Type. Let's see
interface Car {
Brand: string;
Model: string;
}
type KeyofCar = keyof Car; // Brand, Model
if('Brand' is in KeyofCar) {
something...
} // I know it doesn't work but it is pseudocode
Is there any way to find out that?
Upvotes: 10
Views: 22954
Reputation: 267
I'm not sure what you're going for here. In your question you know at compile time that 'Brand'
is in keyof Car
. So why would you check for it?
I could imagine trying to do something like that if the type is not completely known, like in a type argument...
function<T>(foo: T) {
// this is not possible because keyof does not exist in runtime contexts
if('bar' in keyof T) {
// do something...
}
}
I would say you wouldn't try to solve the problem by comparing something to keyof T
. Instead try to do something like this
interface Car {
Brand: string;
Model: string;
}
interface Bus {
Passengers: number;
Color: string;
}
function(foo: Car | Bus) {
if('Brand' in foo) {
// foo is a Car
} else {
// foo is a Bus
}
}
If you really want to do something with the keys you could do something like this
type CarKey = keyof Car;
const carKeys: CarKey[] = ['Brand', 'Model'];
function(key: string) {
if(carKeys.includes(key)) {
// do thing
}
}
Or to be even more sure that you have every key
type CarKey = keyof Car;
const carKeys = Object.keys({
Brand: null,
Model: null
} satisfies Record<CarKey, null>) as Array<keyof Car>;
function isKeyOfCar(key: string): key is CarKey {
return carKeys.includes(key);
}
That way if the Car
type changes over time, you'll know if these keys need to be updated.
Upvotes: 4
Reputation: 3267
type CheckPropExists<T extends {[x:string]:any},Prop extends string> = T[Prop] extends undefined ? false : true;
//Example
type Result = CheckPropExists<{a:string;b:number;},"a">;
//Result is true
Upvotes: 0
Reputation: 36045
As of this writing, there isn't a way to check for this at runtime strictly using Typescript mechanisms. Though a kinda ugly hack you can do is create a Record then extract the keys from it.
interface Car {
Brand: string;
Model: string;
}
const carRecord: Record<keyof Car, boolean> = {
Brand: true,
Model: true
}
if (carRecord['Brand']) {
something...
}
The reason you do a Record
is because every time you change the interface, you must also change the Record
. Otherwise, Typescript will throw compile errors. At the very least this ensures that the check will remain consistent as the Car
interface grows.
Upvotes: 3