Hyena
Hyena

Reputation: 49

How to best match a type definition pattern in TypeScript?

Good evening!

I'm using Angular with rxjs, but I suspect TypeScript is going to be the hero of today. There are many ways to do this, and I've been wracking my brain trying to find the best one. Terribly sorry about the pseudocode, the real one is on a different computer, you'll have to pretend it works I'm afraid.

So I have multiple endpoints all getting different sets of data for me.

getDataA(): Observable<DataTypeA> {
  return get<DataTypeA>httpRequestUrl
    .catchError((error) => return <HttpErrorType>)
}

getDataB(): Observable<DataTypeB> {
  return get<DataTypeB>httpRequestUrl
    .catchError((error) => return <HttpErrorType>)
}

getBothDataSets(): Observable<CombinedDataModel> {
  zip(getDataA, getDataB).pipe(map([dataA, dataB]) => new CombinedDataModel(dataA, dataB))

And then a function that waits for them all to finish, zips them together with rxjs's zip and creates a new CombinedDataModel

interface ICombinedData {
  dataA: DataTypeA | HttpErrorType
  dataB: DataTypeB | HttpErrorType
}

class CombinedDataModel {
  dataA: DataTypeA | HttpErrorType
  dataB: DataTypeB | HttpErrorType

  constructor(dataA, dataB) {
    this.dataA = dataA
    this.dataB = dataB

    some more functions()
  }
}

So now I'm gonna want to know - what type is dataA and dataB, respectively? There are a few different approaches I could take.

if (dataA.status) Would for example work.

Giving all the error types a type: Error field would also work.

Extending the Observable class to have an error field would work.

But what I'd really like to do is to just have a TypeOf function, or at least an isError function, as safety typed as possible. I just haven't seen any of these patterns widely used, so I don't know what approach would be the best to take.

Upvotes: 0

Views: 499

Answers (1)

Alan S. Ferreira
Alan S. Ferreira

Reputation: 74

man, i don't sure if is the best way for your algorithm, the best practice is always specialize not generalize, but if you really want join 2 interfaces may be you be create an type like:

interface ICommon {
  // you can change field 'type' to an field name from {HttpErrorType}
  type: 'A' | 'B' | 'Error';
}
interface DataTypeA extends ICommon {
  type: 'A';
  ... A stuff
}
interface DataTypeB extends ICommon {
  type: 'B';
  ... B stuff
}

and then you can get appropriated type by type field, normally i see this algorithm type, but your code above will works fine too.

Upvotes: 1

Related Questions