I'm trying to solve problem with filter
array function in Typescript, code below:
type Tag = string
type Args = {
tags?: Tag[]
}
const func = async (args: Args) => {
if (args.tags) {
const entities = [
{ tagId: '1' },
{ tagId: '2' }
];
const filtered = entities.filter(entity => args.tags.includes(entity.tagId));
const mapped = args.tags.map(tag => tag + '_test');
}
};
This code throws TS2532 error: Object is possibly undefined when I try to filter the entities
array. For some reasons TS interpreter thinks that args.tags
can be undefined, so include
function can't be called. But as you see, there is a check above, also the map
function works fine.
What can be wrong here? Any thoughts are welcome.
Thanks.
TypeScript doesn't know that filter
's callback runs immediately, so if for example filter
's callback ran later (let's say on a setTimeout
), your code would crash under a call like this:
const a: Args = { tags: [] };
await func(a);
a.tags = undefined;
// Later, the callback runs and accesses 'includes' of the undefined we just set
You can either use !
entity => args.tags!.includes ...
Or stash the value in a const
const tags = args.tags;
if (tags) {
// ...
const filtered = entities.filter(entity => tags.includes ...
type Args = {
tags?: Tag[] // this means --> tags: Tag[] | undefined
}
Use optional chaining and nullish coalescing inside Array.filter()
.
const filtered = entities.filter(entity => args?.tags?.includes(entity.tagId));
The entities array is an array of objects, but the TypeScript compiler is inferring the type as any[]
and doesn't know that the object will contain the tagId
property. Your code should run with the following change:
const entities: {tagId:string}[] = [
Additionally, you want to account for the potentially undefined tags
property in the Args
type:
const filtered = entities.filter(entity => args.tags && args.tags.includes(entity.tagId));
Full code:
type Tag = string;
type Args = {
tags?: Tag[];
};
const func = async (args: Args) => {
if (args.tags) {
const entities: { tagId: string; }[] = [
{ tagId: '1' },
{ tagId: '2' }
];
const filtered = entities.filter(entity => args.tags && args.tags.includes(entity.tagId));
const mapped = args.tags.map(tag => tag + '_test');
}
};
I tested this code with ts-node and tsc (with --lib es2016.array.include
) and received no errors.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.