It's easier to illustrate with code than to explain with words:
// `type` or `interface` doesn't matter to me.
interface MyCollection {
name: string;
age: number;
}
// The best and simplest solution I came up with.
type List<T> = Array<{ key: keyof T}>;
// I want `MyCollection` _keys_ to be present
// as _values_ for `itemkey` prop in `myList` items.
const myList: List<MyCollection > = [
{ itemkey: 'name' },
{ itemkey: 'age' },
]
It's already not bad, because intellisense works and prevents from using wrong keys. But I need to guarantee that every key present in MyCollection
is present in myList
, i.e. current solution allows this:
const myList: List<MyCollection > = [
{ itemkey: 'age' },
]
BONUS: would be the possibility to match MyCollection
key type as well, e.g.:
type List<T> = Array<{ key: keyof T, value: T[keyof T] }>;
// !BAD `value` accepts either `number` or `string`,
// but should only allow `number`.
const myList: List<MyCollection> = [
{ key: 'age', value: 'should be number, not string' },
]
As far as I know there's no possibility to iterate an interface entries to do this.
What I tried is in the description of the problem. I explored mapped types, tuples, remapping via as
and whatever else I could find on the web and in the docs.
Honestly, it's very confusing, a good old JS iteration declaring some kind of static constrains would be way more simpler :D