简体   繁体   中英

Is there a way to use assertion functions with complex validations without creating a specific type?

I'm receiving data from api and I'd like to add some validations on front-end and get correct types after that validations, but really specific ones. For example, suppose I'm getting data with type { keyA?: { property?: string | null | undefined }, keyB?: string | null } | null { keyA?: { property?: string | null | undefined }, keyB?: string | null } | null { keyA?: { property?: string | null | undefined }, keyB?: string | null } | null and I'd like to be sure property is a non empty string, while keyB could be null (just to illustrate I don't want to validate every field, it's not a common NonNull~ case). Is there a way to do it in another function scope (that receives this data) without manually creating a type?

I tried creating a function:

function assertData(data: DType): asserts data {
  if(!data) throw new Error('no data')
  if(!data.keyA) throw new Error('keyA undefined');
  if(!data.keyA.property) throw new Error('property undefined');

After calling the function, I can use data (not null value), but the keyA can be undefined . I expected to able to use data.keyA.property without problems and already typed as string.

You could modify the function to have the following signature:

function assertData(data: DType): asserts data is DType & { 
  keyA: { property: string } 
} {
  if(!data) throw new Error('no data')
  if(!data.keyA) throw new Error('keyA undefined');
  if(!data.keyA.property) throw new Error('property undefined')
}

We assert that data is DType but also that keyA and keyA.property are not undefined.

declare const a: DType
assertData(a)
a.keyA.property.charAt(0)

Playground

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM