I need to create a TypeScript type that guarantees all objects in an array with one key have equivalent keys. The challenge is not knowing what that key will be.
For instance, in the following code snippet, good1
and good2
will pass because
"f1" === "f1"
and "f2" === "f2"
, while bad
would fail since "f3" !== "f4"
.
const good1: MyType = [{ f1: 'Hello' }, { f1: 'World' }];
const good2: MyType = [{ f2: 'Hello' }, { f2: 'World' }];
// @ts-expect-error
const bad: MyType = [{ f3: 'Hello' }, { f4: 'World' }];
A simple approach like Record<string, string>[]
doesn't adequately restrict the keys or their number. In the code below, I'm considering making f
a constant rather than just a string:
type MyType = { [f: string]: string }[];
// Or for a specific number of elements:
type MyTypeTwoElements = [{ [f: string]: string }, { [f: string]: string }];
I want to avoid using generics in the variable declaration because I am unsure of the strings but know they should match (===
). So this won't suffice:
type MyTypeG<F extends string> = Record<F, string>[];
const withGenericsGood: MyTypeG<"f1"> = [{ f1: 'Hello' }, { f1: 'World' }];
//@ts-expect-error
const withGenericsBad: MyTypeG<"f1"> = [{ f2: 'Hello' }, { f3: 'World' }];
There might be a broader scenario where any two strings within a type definition must align, regardless of object keys (and potentially more than two strings).