In the following code:
interface Obj {
requiredKey: string;
optionalKey?: string;
}
type Arr = Array<Obj>;
const arr: Arr = [
{
requiredKey: "a",
optionalKey: "b",
},
{
requiredKey: "c",
},
];
const filtered = arr.filter((obj) => obj.optionalKey);
How do I tell TS that filtered
contains objects where optionalKey
exists? Meaning that the type is now:
{
requiredKey: string;
optionalKey: string;
}[]
CodePudding user response:
You can use the Required
utility type with a user-defined type guard:
interface Obj {
requiredKey: string;
optionalKey?: string;
}
const arr: Array<Obj> = [
{
requiredKey: "a",
optionalKey: "b",
},
{
requiredKey: "c",
},
];
const filtered = arr.filter(
(obj): obj is Required<Obj> => typeof obj.optionalKey === 'string'
);
CodePudding user response:
We can modify Robby's answer slightly, so that it works without hard-coding the Obj
type inside filter
and also without accidentally making unrelated properties required.
const filtered = arr.filter(
(obj): obj is typeof obj & { optionalKey: string } =>
typeof obj.optionalKey === 'string'
);