Consider the following code
type EnforceNonEmptyValue<TValueArg extends string> = {
value: TValueArg extends '' ? never : TValueArg
type: 'substringMatch'
}
function identity<
TValueArg extends string
>(
object: EnforceNonEmptyValue<TValueArg>
) {
return object
}
// rightfully complaints
identity({value: '', type: 'substringMatch'})
//---------^
// `Type 'string' is not assignable to type 'never'.ts(2322)`
// works
identity({value: 'works', type: 'substringMatch'})
The function identity with the help of EnforceNonEmptyValue generic enforces that the object passed to the function has a non empty string value, i.e. the value of value property should not be an empty string ''
I want to extend this check for an array of objects
identityArray([
{
type: 'substringMatch',
value: 'np-payment',
},
{
type: 'substringMatch',
value: '',
//------^ should complain here
},
])
i.e I want typescript to throw an error if any object in an array of objects has a value property's value as an empty string ''
But I've been having a hard time to make it work. How could we enforce it for an array of objects? ( with or without an identity function )
You can use a mapped array/tuple type as shown here:
The compiler can infer the type
Tfrom the homomorphic mapped type (see What does "homomorphic mapped type" mean?){[I in keyof T]: EnforceNonEmptyValue<T[I]>}. I wrapped it with a variadic tuple type ([...+]) to give the compiler a hint that we'd likeTto be inferred as a tuple type and not as an unordered array type, but you might not care either way.Anyway, let's test it:
Looks good. The compiler accepts
"np-payment"and rejects"". You can see thatTis inferred as the tuple type["np-payment", ""]and theargsargument is of the mapped tuple type[EnforceNonEmptyValue<"np-payment">, EnforceNonEmptyValue<"">].Playground link to code