Typescript: Allow identifying readonly properties in mapped types

Created on 24 May 2019  路  1Comment  路  Source: microsoft/TypeScript

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:

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

Most helpful comment

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 ).

>All comments

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 ).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dlaberge picture dlaberge  路  3Comments

bgrieder picture bgrieder  路  3Comments

manekinekko picture manekinekko  路  3Comments

Roam-Cooper picture Roam-Cooper  路  3Comments

kyasbal-1994 picture kyasbal-1994  路  3Comments