I have a function something like:
function allFinished(pendingProps: string[], allProps: Record<string, unknown>): boolean {
return pendingProps.every((pendingProp) => allProps[pendingProp].isFinished)
}
For typescript to be happy with me, it needs to know that each allProps key which is an element of pendingProps will have a value that includes isFinished. But I also need it to be okay with keys which are not in pendingProps having a different value type.
This would be fairly simple if pendingProps was defined ahead of time and could be marked as const, but I can't figure out how to do this with with an arbitrary string array.
CodePudding user response:
We should make allFinished generic for this to be properly typed.
function allFinished<
T extends Record<K, { isFinished: boolean }> & Record<string, unknown>,
K extends string
>(pendingProps: K[], allProps: T): boolean {
return pendingProps.every((pendingProp) => allProps[pendingProp].isFinished)
}
The essentially expresses the constraints you mentioned in your question. All pendingProps will be stored in K while the allProps object is stored in T. T is constrained so that every property where the key is part of K must have a property isFinished. But every other string property will have an unknown type.
Let's see if this works:
allFinished(["a", "b", "c"], {
a: { isFinished: true },
b: { isFinished: false },
c: {}, // Error: Property 'isFinished' is missing in type '{}' but required in type '{ isFinished: boolean; }'
d: {}
})
