Skip to content

Restrict Paths for rename, remove and upsert #21

@anthonyjoeseph

Description

@anthonyjoeseph

🚀 Feature request

Current Behavior

rename, remove and upsert suggest all the same paths as get, set etc.

Desired Behavior

rename & remove:

  • should only suggest paths that end in an object's key (ones that don't end in '?' or sum-type-narrowing)

upsert:

  • should only suggest paths that end with a struct or record

Suggested Solution

This solution was proposed:

type UpsertableKeys<A> = Extract<
  keyof {
    [K in keyof A as true extends IsRecord<A[K]> ? K : never]: unknown;
  },
  string
>;

type ExtractChangeableKeys<A> = Extract<
  keyof {
    [K in keyof A as true extends IsNull<A[K]> ? never : Discriminant<A[K]> extends never ? K : never]: unknown;
  },
  string
>;

type Operation = "static" | "dynamic" | "upsert"

type _Paths<A, Op extends Operation, Acc extends string = never> = true extends IsRecord<A>
  ? _Paths<
      keyof A extends never ? unknown : BubbleUp<A>,
      Op,
      | Acc
      | (Op extends "static"
          ? Extract<keyof A, string>
          : Op extends "upsert"
          ? UpsertableKeys<A>
          : ExtractChangeableKeys<A>)
    >
  : Acc;

But it was determined that this caused deep type instantiation that adversely affected performance

Who does this impact? Who is this for?

users of rename, remove and upsert

Describe alternatives you've considered

Worst comes to worst, we could continue to emit those keys from Paths but give some other type of compile-time error

Additional context

Your environment

Software Version(s)
spectacles-ts 1.0.6
fp-ts 2.11
TypeScript 4.6

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions