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: {}
})