There is a custom type Options
(nested object) that I created. I want to use the type DefaultProperties
to create an object that contains the default properties.
type Options = {
id: number,
text: string | undefined,
properties: {
title: string,
subtitle: string | undefined,
}
}
type DefaultProperties = Pick<Options, "properties">;
Of course the default properties cannot be undefined
. So I want to exclude undefined
from my union types.
For that purpose there should be a build-in functions like NonNullable<T>
or Exclude<T,UnionType>
.
I tried three different ways to remove undefined
but no solution is working with my type.
type Options = {
id: number,
text: string | undefined,
properties: {
title: string,
subtitle: string | undefined,
}
}
type DefaultProperties = Pick<Options, "properties">;
// Try #1: does not work
type Type1 = NonNullable<DefaultProperties>;
// Try #2: does not work
type NotOptional<Type> = {
[Property in keyof Type]-?: Type[Property];
};
type Type2 = NotOptional<DefaultProperties>;
// Try #3: does not work
type Type3 = Exclude<Options, undefined>;
Example: TypeScript Playground
How can I remove all undefined
s from all of my type union types?
Edit:
All undefined
s should be removed from my type. For example:
Options['text'] : string
(No moreundefined
)Options['properties']['subtitle'] : string
(No moreundefined
)
Later I want to use the type for this (for example):
const options : Options = { ... };
const defaults: DefaultProperties= { ... }; // With no undefined
const node : HTMLElement = .... ;
node.innerHTML = options.properties.subtitle !== undefined ? options.properties.subtitle : defaults.properties.subtitle;
When defaults.properties.subtitle
has the type string | undefined
, the compiler throws an error because innerHTML
only allows strings
. For that I want to exclude undefined
.
CodePudding user response:
You're really close with your NotOptional
utility type and Exclude
, the problem is that you're defining DefaultProperties
as an object with a properties
property, but you're trying to remove undefined
from DefaultProperties
, not from its properties
property.
In a comment you've said you want DefaultProperties
to be the same shape as properties
on Options
. That means the basic shape of it (before we try to remove undefined
) is Options["properties"]
. So:
type NotOptional<Type> = {
[Property in keyof Type]: Exclude<Type[Property], undefined>;
};
type DefaultProperties = NotOptional<Options["properties"]>;
Tests:
const defaults1: DefaultProperties = {
title: "foo",
subtitle: undefined, // <== Error as desired
};
const defaults2: DefaultProperties = {
title: "foo",
subtitle: "something", // <== No error
};
You might also consider removing optionality (combining two of the things you tried):
type NotOptional<Type> = {
[Property in keyof Type]-?: Exclude<Type[Property], undefined>;
};
type DefaultProperties = NotOptional<Options["properties"]>;
Tests:
const defaults1: DefaultProperties = {
title: "foo",
subtitle: undefined, // <== Error as desired (wrong type for `subtitle`)
};
const defaults2: DefaultProperties = { // <== Error as desired (missing `somethingElse`)
title: "foo",
subtitle: "something",
};
const defaults3: DefaultProperties = { // <== No error
title: "foo",
subtitle: "something", // <== No error
somethingElse: "x",
};