1

I am receiving some json object from a file, and I want to parse some of the fields to predefined values.

import jobsRaw from '../../data/jobs.json';

I created a type that describes my object, but I want the status to have only my predefined values, if else I might define a fallback value.

export type Job = {
  type: string;
  id: string;
  status: JobStatus;
  warehouseId: string;
  relatedCell: string;
  relatedDocument: string;
  partnerName: string;
  potatoType: string;
  relatedBoxes: string[];
  boxCount?: number;
  createdAt: string;
  completedAt: string;
};

This is the mapping I'm trying with:

const jobs: Job[] = jobsRaw.map((job: Job) => ({
  ...job,
  status: JobStatus[job.status],
  boxCount: job.relatedBoxes.length,
}));

I want to create some sort of JobStatus type that I can parse my received string value with.

1 Answer 1

2

If I had to implement this I would go for a type predicate to check if the data is a proper JobStatus. Maybe something like this:

const isJobStatus = (value: any): value is JobStatus =>
  value && Object.values(JobStatus).includes(value);

const jobs: Job[] = jobsRaw.map((job: Job) => ({
  ...job,
  status: isJobStatus(job.status) ? job.status : JobStatus.SOME_DEFAULT_STATUS,
  boxCount: job.relatedBoxes.length,
});

With this approach you could even use a different type in map iterator like below to better represent the "raw" data because the type predicate will cast job.status as a proper JobStatus when it returns true. I've also made boxCount mandatory in Job and removed it from JobRaw, by doing like this you won't need to make it optional.

export type Job = {
  type: string;
  id: string;
  status: JobStatus;
  warehouseId: string;
  relatedCell: string;
  relatedDocument: string;
  partnerName: string;
  potatoType: string;
  relatedBoxes: string[];
  boxCount: number;
  createdAt: string;
  completedAt: string;
};

type JobRaw = Omit<Job, 'status' | 'boxCount'> & { status: string };

const jobs: Job[] = jobsRaw.map((job: JobRaw) => ({
  ...job,
  status: isJobStatus(job.status) ? job.status : JobStatus.SOME_DEFAULT_STATUS,
  boxCount: job.relatedBoxes.length,
}));
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.