Skip to content

Set.has() and Array.includes() should narrow the type of their argument to the type of this when they return true #51678

Closed
@jyasskin

Description

@jyasskin

lib Update Request

Configuration Check

My compilation target is ES2022 and my lib is the default.

Missing / Incorrect Definition

Set.has() and Array.includes() should narrow the type of their argument to the type of this when they return true (which implies they should accept wider types as arguments).

This is probably impossible until #14520 is solved, but I wanted to add a more concrete use case than just making it convenient to pass wide arguments.

Sample Code

type Ingredient = {
  amount?: string;
  unit?: string;
  name?: string;
}
const ingredientKeys = new Set(["amount", "unit", "name"] as const);

let key: string = "...";
let value: string = "...";
let result: Ingredient = {};
// Doesn't work but should:
if (ingredientKeys.has(key)) {
  result[key] = value;
}

// Works, but can't do it as a member function:
function has<T extends U, U>(set: ReadonlySet<T>, elem: U): elem is T {
  const wider: ReadonlySet<U> = set;
  return wider.has(elem);
}
if (has(ingredientKeys, key)) {
  result[key] = value;
}

Playground Link

Documentation Link

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions