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

Inconsistent behaviour of Pick<T, keyof T> for readonly attributes. #14295

Closed
fahrradflucht opened this issue Feb 24, 2017 · 5 comments · Fixed by #55541
Closed

Inconsistent behaviour of Pick<T, keyof T> for readonly attributes. #14295

fahrradflucht opened this issue Feb 24, 2017 · 5 comments · Fixed by #55541
Labels
Bug A bug in TypeScript
Milestone

Comments

@fahrradflucht
Copy link

fahrradflucht commented Feb 24, 2017

TypeScript Version: 2.2.1

Code
Typescript Playground

// This fails:

interface TestA {
    readonly foo: string;
}

type MutableTestA = Pick<TestA, keyof TestA>

const a: MutableTestA = {
    foo: 'bar'
}

a.foo = 'baz';

// This works:

interface TestB {
    readonly [key: string]: string;
}

type MutableTestB = Pick<TestB, keyof TestB>

const b: MutableTestB = {
    foo: 'bar'
}

b['foo'] = 'baz';

In Typescript 2.1.4 you could use Pick<> to remove the readonly modifier from all attributes of an interface T by calling Pick<T, keyof T>. From 2.1.5 this (mostly) doesn't work anymore. "Mostly" because it does still work for readonly index signatures.

Expected behavior:
I personally would prefer if there would be some way to make an object mutable analog to Readonly<>but at least the behaviour should be consistent.

Actual behavior:
The behaviour is inconsistent.


Edit:

I bisected this and it seems like 33b5125 that types propagate modifiers when using Pick<T, K> which suggests that the behaviour of the index signature example is the bug.

@pablobirukov
Copy link

pablobirukov commented Mar 13, 2017

Seems like there is no way to reset readonly modifier which is not very convenient

const foo = {
    bar: "baz",
}
const readonlyFoo = Object.freeze(foo);
const writableFoo = { ...readonlyFoo };
writableFoo.bar = "not a buz, but something else";
            ~~~  [ts] Cannot assign to 'bar' because it is a constant or a read-only property.

@pablobirukov
Copy link

@RyanCavanaugh will you please take a look at the problem? If I understand correctly it is an issue

@mhegazy mhegazy added the Bug A bug in TypeScript label Mar 28, 2017
@mhegazy
Copy link
Contributor

mhegazy commented Mar 28, 2017

@R00GER your issue with spread is a different issue, please see #14058.

The fix for the issue in the OP is to make the resulting string indexer inherit readonly (as well as optionality) in a homomorphic mapped type, just like it does with named properties.

@jcalz
Copy link
Contributor

jcalz commented May 9, 2019

So, this is still a bug, right? But instead of there being no way to remove modifiers (which was addressed in TS2.8), there is now no way to preserve the readonly modifier on an index signature when you map over it. Should that be filed as a separate bug and have this one closed, or should it live on here?

@sandersn sandersn removed their assignment Jan 7, 2020
@unicornware
Copy link

@RyanCavanaugh

there is now no way to preserve the readonly modifier on an index signature when you map over it. Should that be filed as a separate bug and have this one closed, or should it live on here?

i'm facing this issue as well. should this be filed as a separate bug?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants