3

So I have an object with some standard property names and some random. I would like an interface that forces types for the known properties (lets say name,age) and also forces that all other properties are of type boolean. Is this possible somehow?

interface IUser {
  name: string;
  age: number;
}
type IWishThisWouldWork = IUser & { [key: Exclude<string, keyof IUser>]: boolean }

const x: IWishThisWouldWork = {
  name: 'john', //required and allow only string
  age: 5, //required and allow only number
  randomProp1: true, //allow only boolean
  randomProp2: false //allow only boolean
}
prof chaos
  • 404
  • 3
  • 18
  • This is currently not possible; for various workarounds see the linked duplicate question. – jcalz Oct 12 '22 at 14:49

1 Answers1

1

There is unfortunately no way to do it, when you specify a type like {[key]: someType}, the type someType should also include all the types of the known keys.

The reason is that otherwise there would be situations where Typescript cannot know the type of an expression.

For instance in your example what should the type of x["NAME".toLowercase()] be? boolean would be wrong but string would require Typescript to run arbitrary code, which would be crazy.

Or if you have a variable key: string, what is the type of x[key]? We don't know because it depends on the value of key.

As a workaround I would suggest to separate the known and unknown properties (if you can change the way the data is stored). For instance

type UserWithProps = {
  name: string, 
  age: number, 
  otherProps: {
    [key]: boolean, 
  }, 
}

Then you need to add a .otherProps to access the boolean properties, but at least the typing is easy now. The original type that you are trying to construct is also potentially flawed anyway. Where are those random props coming from? If they are for instance coming from user input, then you run a risk of conflict if the user happens to choose name or age.

Guillaume Brunerie
  • 4,676
  • 3
  • 24
  • 32
  • 1
    related typescript issue: [Need way to express hybrid types that are indexable for a subset of properties #17867](https://github.com/microsoft/TypeScript/issues/17867) – TmTron Oct 12 '22 at 11:54