Skip to content

Array of generic functions not assignable to ReadonlyArray #20454

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

Closed
ghost opened this issue Dec 4, 2017 · 4 comments
Closed

Array of generic functions not assignable to ReadonlyArray #20454

ghost opened this issue Dec 4, 2017 · 4 comments
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@ghost
Copy link

ghost commented Dec 4, 2017

TypeScript Version: 2.7.0-dev.20171203

Code

type Fn<T> = <U extends T>(x: U) => U
function f<T, T1 extends T>(fns: Array<Fn<T>>, t1: T1) {
    const a: ReadonlyArray<Fn<T1>> = fns; // This is an error

    const b: ReadonlyArray<Fn<T>> = fns;
    const c: ReadonlyArray<Fn<T1>> = b; // But this works
}

Expected behavior:

No error.

Actual behavior:

src/a.ts(3,11): error TS2322: Type 'Fn<T>[]' is not assignable to type 'ReadonlyArray<Fn<T1>>'.
  Types of property 'includes' are incompatible.
    Type '(searchElement: Fn<T>, fromIndex?: number) => boolean' is not assignable to type '(searchElement: Fn<T1>, fromIndex?: number) => boolean'.
      Types of parameters 'searchElement' and 'searchElement' are incompatible.
        Types of parameters 'x' and 'x' are incompatible.
          Type 'U' is not assignable to type 'T1'.
            Type 'T' is not assignable to type 'T1'.
@ghost
Copy link
Author

ghost commented Dec 14, 2017

A possibly related problem:

declare function flatten<T>(array: ReadonlyArray<ReadonlyArray<T>>): T[];
declare const x: number[][];
const y = flatten(x); // Got `{}[]`, wanted `number[]`.

Works with an explicit type argument flatten<number>.

@aj-r
Copy link

aj-r commented Mar 26, 2018

Possibly related issue: generic type is not inferred correctly for ReadonlyArray<keyof T>.

function at<T>(object: T, key: ReadonlyArray<keyof T>): Array<T[keyof T]> {
    // Do stuff...
}
let result: number[];
result = at({ a: 1, b: 2 }, ["a"]); // Error: Argument of type '{ a: number; b: number; }' is not assignable to parameter of type '{ a: any; }'.
result = at({ a: 1, b: 2 }, ["a", "b"]); // Error: Argument of type '{ a: number; b: number; }' is not assignable to parameter of type '{ a: any; }'.
const obj = { a: 1, b: 2 };
result = at(obj, ["a", "b"]); // Error: Argument of type '("a" | "b")[]' is not assignable to parameter of type 'ReadonlyArray<"a">'.
result = at<{ a: number, b: number }>({ a: 1, b: 2 }, ["a", "b"]); // Works

Changing ReadonlyArray<> to Array<> in the function definition fixes the error.

@mhegazy mhegazy added Design Limitation Constraints of the existing architecture prevent this from being fixed and removed Bug A bug in TypeScript labels Jul 20, 2018
@mhegazy
Copy link
Contributor

mhegazy commented Jul 20, 2018

comparing array to ReadonlyArray structurally with --strictFunctionTypes on leads to them being invariant. we get away with this on Array because of our type reference optimization.

@typescript-bot
Copy link
Collaborator

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

3 participants