Skip to content

Allow identifying readonly properties in mapped types #31581

Open

Description

@inad9300

Search Terms

Pretty much the ones in the title...

Suggestion

Any TypeScript modifier should be allowed to be easily identified in mapped types. In particular, readonly should, but possibly others too, such as ?.

Use Cases

Define mapped types where the values depend on whether the property is readonly or not. At the moment, the following madness is necessary for this:

 type Or<A extends boolean, B extends boolean> = A extends true
    ? true
    : B extends true
        ? true
        : false

type Equals<X, Y> =
    (<T> () => T extends X ? 1 : 2) extends
        (<T> () => T extends Y ? 1 : 2)
            ? true
            : false

type IsReadonly<O extends Record<any, any>, P extends keyof O> =
    Not<Equals<{[_ in P]: O[P]}, {-readonly [_ in P]: O[P]}>>

I would like to see some syntactic sugar similar to (not intended to be a full implementation):

type Writable<T> = {
    [P in keyof T]: isreadonly T[P] ? never : T[P]
}

In my case, I would like to define a hyperscript-style function which accepts a series of attributes for the creation of HTML elements. For this, I reuse the interfaces that TypeScript defines, such as HTMLAnchorElement, but obviously readonly properties (among others) need to be excluded.

Other people seem to have similar use cases, e.g. https://stackoverflow.com/questions/52443276/how-to-exclude-getter-only-properties-from-type-in-typescript

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

Activity

  1. jcalz commented on May 24, 2019

    @jcalz
    Contributor

    I'd be interested in more streamlined manipulation of modifiers in mapped types. Detecting readonly and optional properties is indeed a bunch of hoop jumping, and then if you want to selectively alter the modifiers, you need to split the mapping into pieces and intersect them:

    type SelectivePartial<T, K extends keyof T> =
      Partial<Pick<T, K>> & Required<Pick<T, Exclude<keyof T, K>>> extends
      infer U ? { [P in keyof U]: U[P] } : never;
    
    type Foo = SelectivePartial<{ a: string, b: number, c?: boolean }, 'b'>
    // type Foo = { b?: number | undefined; a: string; c: boolean; }

    It would be a lot nicer to essentially read and selectively write modifiers inside the mapping directly. (Note the word "selectively"; the current support for altering modifiers is all-or-nothing ).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions