Skip to content

Narrowing with in keyword and const identifierΒ #61463

Closed as not planned
Closed as not planned
@yeomanse

Description

@yeomanse

πŸ” Search Terms

"narrowing", "in", "const", "identifier"

βœ… Viability Checklist

⭐ Suggestion

Currently narrowing with the in keyword only works with a string literal in the if or if the identifier's type is a string literal. However, a const identifier with the type of a union of string literals feels like it should work the same way.
It can only ever be one of the literals and thus be a good candidate for narrowing.

For example:

export type Obj_Values = {
    values_string: string[];
    values_double: number[];
    values_int: number[];
    values_date: Date[];
    values_boolean: boolean[];
};
export type Obj_Key = keyof Obj_Values;
export type Obj_Choice<SELECTOR extends Obj_Key> = SELECTOR extends any ? Pick<Obj_Values, SELECTOR> : never;
export type Obj = Obj_Choice<Obj_Key>;

const obj: Obj;
const key: Obj_Key;

if (key in obj) {
    console.log(obj[key])  // Error below
    console.log((obj as Obj_Values)[key])  // Unfortunate work around
}

//Element implicitly has an 'any' type because expression of type 'keyof Obj_Values' can't be used to index type 'Obj'.
//  Property 'values_string' does not exist on type 'Obj'.(7053)

This might be easier said than done as there doesn't exist a way to convey what the post narrow type would even look like. But it seems like a good thing to talk about.

πŸ“ƒ Motivating Example

Further improving narrowing in situations where runtime code is dynamic enough to not want to use string literals but the literals are known in the types.

πŸ’» Use Cases

  1. What do you want to use this for?
    Code that uses types generated off of schemas but the runtime code doesn't need to be coupled to schema changes by requiring updates where narrowing happens.
  2. What shortcomings exist with current approaches?
    Lack of narrowing pushes you towards unsatisfactory workarounds.
  3. What workarounds are you using in the meantime?
    Casting to types that are lies or any.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions