Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Cast Partial<T> to T for an anonymous type

I have an array of values of a partial type that is not explicitly defined anywhere. (In my case, it’s the .value of an Angular FormArray<FormGroup<...>>, but it doesn’t really matter).

The type that I have could be spelled out as Partial<{ foo: string; bar: string; baz: string; buz: string }>[]. Now, I am only interested in the values that actually contain data, so I do this:

const myArray: Partial<{ foo: string; bar: string; baz: string; buz: string }>[] 
    = ...;
const filteredArray = myArray.filter((x) => x.foo && x.bar && x.baz && x.buz);

Obviously, filteredArray will not contain any objects with undefined fields. However, TypeScript still infers the type of filteredArray as Partial<{ foo: string; bar: string; baz: string; buz: string }>[], same as myArray – because the compiler has no insight into the semantics of the .filter(1) method, it cannot infer that the actual type of filteredArray is the more specific type { foo: string; bar: string; baz: string; buz: string }[].

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Now, of course, the compiler can be helped along like this:

const correctlyTypedArray = filteredArray 
    as { foo: string; bar: string; baz: string; buz: string }[];

However, this requires me to spell out the entire structure of the anonymous type, which is very inconvenient. In this case, the interface only has four fields, but in actual practice, it may be much more than that. This makes the cast ridiculously unwieldy, and also requires me to change each site where such a cast happens every time something about the anonymous type changes.

Obviously, I could create a definition somewhere and just declare type Frobnicator = { foo: string; bar: string; baz: string; buz: string }, which enables me to just cast filteredArray as Frobnicator[], but that still adds a maintenance burden and is annoying busywork.

How can I cast a value of type Partial<T> (or Partial<T>[]) to T (or T[]), without having to spell out the type T?

>Solution :

You are looking for the Required<T> utility type (the opposite of Partial<T>).

But since you’re filtering on an array, you need to move the filter function out and put a type predicate on it:

type PartialWidget = typeof myForm.value
type Widget = Required<PartialWidget>

const isWidget = (x: Partial<Widget>): x is Widget =>
  x.foo && x.bar && x.baz && x.buz

// usage:
myArray.filter(isWidget)
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading