Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Mapped Types syntax to remove modifiers #13723

Closed
marcomura opened this issue Jan 27, 2017 · 6 comments
Closed

Proposal: Mapped Types syntax to remove modifiers #13723

marcomura opened this issue Jan 27, 2017 · 6 comments
Labels
Fixed A PR has been merged for this issue Suggestion An idea for TypeScript

Comments

@marcomura
Copy link

Current TypeScript Version: 2.1.1

We have a syntax to add "readonly" to every property of a type. Unfortunately, it seems there is no way to have the reverse operation: removing it.
This is useful for creating Mocked version of types for UTs, which have readonly fields in production.

This should work recursively.

Code

interface MyType2 {
  readonly z1: number;
  z2: string;
}

interface MyType {
  readonly a: number;
  readonly b: MyType2;
  c: string;
  d: MyType2;
}

type Mock<T> {
  [P in keyofwithoutmodifiers T]: Mock<T[P]>;
}

type MyMockedType = Mock<MyType>;

Expected behavior:
type MyMockedType to be

{
  a: number;
  b: { z1: number; z2: string };
  c: string;
  d: { z1: number; z2: string };
}

Actual behavior:
not possible right now

@mhegazy
Copy link
Contributor

mhegazy commented Jan 27, 2017

I do not think we will be adding yet another construct to remove readonly and optionality in mapped types; we have a limited budget of complexity and every new concept comes in with its cost both for language users and maintainers.

You can do this today by breaking the homomorphic relationship between the target of the map and the result; to do so you need to disassociate the key from the type. e.g.:

type Mutable<T extends { [x: string]: any }, K extends string> = {
    [P in K]: T[P];
}

type Mock<T> = Mutable<T, keyof T>;

@mhegazy mhegazy added Suggestion An idea for TypeScript Declined The issue was declined as something which matches the TypeScript vision labels Jan 27, 2017
@fahrradflucht
Copy link

@mhegazy your code example is a solution if you want to transform

interface TypeA {
  readonly name: string;
}

to

interface TypeB {
  name: string;
}

But if you have

interface TypeA {
  readonly name: string;
  readonly color?: string;
}

and this would transform it to this

interface TypeB {
  name: string;
  color: string;
}

which is more then just removing the modifiers.

In combination with Partial<T> it is possible to remove all modifiers and make everything optional or make everything required but is isn't possible to just remove the modifiers and keep the original mix of required and optional fields or is it?

@mhegazy
Copy link
Contributor

mhegazy commented Feb 27, 2017

it is possible to remove all modifiers and make everything optional or make everything required but is isn't possible to just remove the modifiers and keep the original mix of required and optional fields or is it?

No; we will need to add a new mutable/readwrite modifier to undo the readonly modifier effect. but as i noted earlier, there is limited budget to adding concepts in the language.

@DanielRosenwasser
Copy link
Member

I think this was fixed by #21919.

@DanielRosenwasser DanielRosenwasser added Fixed A PR has been merged for this issue and removed Declined The issue was declined as something which matches the TypeScript vision labels May 11, 2018
@knpwrs
Copy link

knpwrs commented Jun 9, 2018

It definitely appears that way. The following works for me:

type Mutable<T> = {
    -readonly [P in keyof T]: T[P];
};

@ffMathy
Copy link

ffMathy commented Feb 2, 2019

What if I want to remove the "private" keyword?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Fixed A PR has been merged for this issue Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

6 participants