Typescript: Readonly<Float32Array> not assignable to Float32Array

Created on 4 May 2019  路  7Comments  路  Source: microsoft/TypeScript


TypeScript Version: 3.4.0-dev.201xxxxx


Search Terms:

Code

function update(b: Readonly<Float32Array>) {
    const c = copy(b);
    add(c, c);
}

function add(a: Float32Array, b: Float32Array, c: Float32Array = a) {
    c[0] = a[0] + b[0];
}

function copy(a: Float32Array) {
    return new Float32Array(a);
}

Expected behavior:

No error.

_Though I would expect not to be able to pass a Readonly value to a function which can mutate it but that's another issue_.

Actual behavior:

Error on line 2:

Argument of type 'Readonly<Float32Array>' is not assignable to parameter of type 'Float32Array'.
  Type 'Readonly<Float32Array>' is missing the following properties from type 'Float32Array': [Symbol.iterator], [Symbol.toStringTag]

Playground Link:

See in playground

Note I can workaround the issue by using mappable types on the function arguments but this is pretty verbose and not something I will want to litter a codebase with - Also not going to work with third-party libraries. See that here. Edit: Actually seen another way to do it which is much less verbose here. _This however loops again back to this issue since it really should be raising an error (if in strict mode)._

Related Issues:

N/A

Bug Mapped Types

All 7 comments

This is聽caused by聽the聽fact that symbols aren鈥檛 preserved by聽mapped types.

This is caused by the fact that symbols aren鈥檛 preserved by mapped types.

Yep, or more specifically, they鈥檙e not exposed by keyof. I鈥檓 trying to dig up why that is, but changing it would likely be a _huge_ breaking change... @weswigham what are your thoughts here?

Mapped types _do_ retain symbol keys - Certain builtin symbols (ie, Symbol.iterator) we know of predate unique symbols and do not appear in any object key lists - #24738 was originally opened to address this, and typesVersions was made to make the migration to real unique symbols for these global symbols better.

Got it. In a sense, then, this is a duplicate of #24622. At least, I think it鈥檚 blocked on #24738.

Certain builtin symbols (ie, Symbol.iterator) we know of predate unique symbols and do not appear in any object key lists

Glad to see this is being fixed, just found out that this does not currently work:

const asyncIterable: AsyncIterable<number> = Object.freeze({
  * [Symbol.asyncIterator]() {
    yield 1
    yield 2
  },
})

@DanielRosenwasser @RyanCavanaugh this is in the 3.6.1 milestone, but I don鈥檛 think it鈥檚 actionable without #24738, which, uh, probably cannot go into 3.6.

@weswigham can you please explain how is this a bug?

it seems that if copy wants a mutable Float32Array and you give it an immutable (readonly) Float32Array it's defiantly a mistake because you can't modify immutable data but if you wanted mutable data then you probably will try to mutate it (if you have no plans to mutate data you can change type annotation to be immutable (readonly) like so Readonly<Float32Array> and it will work fine)


edit

this part is a bug Type 'Readonly<Float32Array>' is missing the following properties from type 'Float32Array': [Symbol.iterator], [Symbol.toStringTag]

my mistake ...

Was this page helpful?
0 / 5 - 0 ratings