Getting rid of unknown in TypeScript casting

79 Views Asked by At

I wrote the below code.

  const incompleteKYCClaims = completedProvidersWithoutStripeAccount.map( async (p) => {
    const provider = await getProviderOrThrow(p.tin)
    const isPreviouslyApproved = previouslyApproved.includes(provider.status)
    if (isPreviouslyApproved) return
    return toProviderRelationshipClaims({tin: p.tin, role: ProviderUserSubRoles.ky, status: 'KYCInDraft'})
  }).filter(claim => !!claim) as unknown as Array<ProviderRelationshipClaims>

It maps an array to another array skipping entries where isPreviouslyApproved is true.

In order for type-checking to pass, I have to convert Array<ProviderRelationshipClaims | unknown> to unknown then convert that to Array<ProviderRelationshipClaims>. This should not be necessary as filter(claim => !!claim) will filter-out undefined. However, typescript checker does not get this. At least, this is how I interpret this.

How could I get rid of conversion to unknown, and/thus to make this code fragment nicer [more elegant]? Any recommendations?

Thank you

1

There are 1 best solutions below

0
Max On

Think that adding a return type to the filter will work for you.

If I understand the issue, its basically like this example right?

const arr = [1, 2, 3, undefined, 4];

const filtered = arr.filter(x=>x!==undefined); //(number | undefined)[] .. 

but should be number array.

If you do

const filtered = arr.filter((x):x is number=>x!==undefined); //number[]

then you get number array.

So for your code, if you know the type you can do

.filter((claim): claim is ProviderRelationshipClaims => !!claim)

assuming ProviderRelationshipClaims is the type other than undefined.

Otherwise I think that you can do this

arr.filter(<T extends unknown>(z:T): z is Exclude<T,undefined> => z !== undefined);

which I guess should work for most types