2

I have code to prepend element to array. It works great on playground check the playground link But when i run same code locally it works another.

export type ArrayWrap<T> = T extends any[] ? T : [T];

export type PrependArray<A, B extends Array<any>> = B extends any[]
    ? ((a: A, ...b: B) => any) extends (...args: infer U) => any
        ? U
        : never
    : ArrayWrap<A>;

type T = PrependArray<"a", ["b"]>; // expected ["a", "b"] but makes ["a", ..."b"[]]

Not sure if it could be related to config of TS

Edit 2: So i found that in one package of project it is as expected in second (Storybook package) it seems it is wrong.

Working package TS config:

{
    "compilerOptions": {
        "target": "es5",
        "lib": ["dom", "dom.iterable", "esnext"],
        "allowJs": true,
        "skipLibCheck": true,
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "strict": true,
        "forceConsistentCasingInFileNames": false,
        "module": "esnext",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "noEmit": true,
        "jsx": "preserve",
        "experimentalDecorators": true,
        "strictNullChecks": false
    },
    "include": ["src"]
}

Not working package TS config:

{
    "compilerOptions": {
        "outDir": "build/lib",
        "module": "commonjs",
        "target": "es5",
        "lib": ["es5", "es6", "es7", "es2017", "dom"],
        "sourceMap": true,
        "allowJs": false,
        "jsx": "react",
        "moduleResolution": "node",
        "rootDirs": ["stories", "test"],
        "baseUrl": ".",
        "forceConsistentCasingInFileNames": true,
        "resolveJsonModule": true,
        "noImplicitReturns": true,
        "noImplicitThis": true,
        "noImplicitAny": true,
        "strictNullChecks": true,
        "suppressImplicitAnyIndexErrors": true,
        "noUnusedLocals": true,
        "allowSyntheticDefaultImports": true,
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "esModuleInterop": true,
        "isolatedModules": true,
        "noEmit": false
    },
    "include": ["stories/**/*", "test/**/*"],
    "exclude": ["node_modules", "build", "scripts"]
}
luky
  • 2,263
  • 3
  • 22
  • 40
  • 2
    Maybe they just have a bug in 3.7.4? FYI here are the links for all the tickets solved https://github.com/microsoft/TypeScript/releases/tag/v3.7.5 – Pac0 Jun 11 '20 at 12:28
  • @Pac0 i tried 3.7.5 locally and same error but thanks – luky Jun 11 '20 at 12:34

1 Answers1

1

So the reason of different function was "strict": true (works good) or "strict": false (or not set works bad). Could I affect the behaving also in some other way, or use the array prepend another way?

Another option that affects it: "strictFunctionTypes": true (works good), false works bad. (or don't set "strict":true but only this true and it works) - replicable also on TS playground this one.

But I ended with this code, which works also without strict: true.

export type PrependArray<Val, T> = T extends [
    infer A,
    infer B,
    infer C,
    infer D,
    infer E,
    infer F,
    infer G,
    infer H,
    infer I,
    infer J
]
    ? [Val, A, B, C, D, E, F, G, H, I, J]
    : T extends [infer A, infer B, infer C, infer D, infer E, infer F, infer G, infer H, infer I]
    ? [Val, A, B, C, D, E, F, G, H, I]
    : T extends [infer A, infer B, infer C, infer D, infer E, infer F, infer G, infer H]
    ? [Val, A, B, C, D, E, F, G, H]
    : T extends [infer A, infer B, infer C, infer D, infer E, infer F, infer G]
    ? [Val, A, B, C, D, E, F, G]
    : T extends [infer A, infer B, infer C, infer D, infer E, infer F]
    ? [Val, A, B, C, D, E, F]
    : T extends [infer A, infer B, infer C, infer D, infer E]
    ? [Val, A, B, C, D, E]
    : T extends [infer A, infer B, infer C, infer D]
    ? [Val, A, B, C, D]
    : T extends [infer A, infer B, infer C]
    ? [Val, A, B, C]
    : T extends [infer A, infer B]
    ? [Val, A, B]
    : T extends [infer A]
    ? [Val, A]
    : ArrayWrap<Val>;

Inspired by this guy's answer https://stackoverflow.com/a/53985533/4870273

luky
  • 2,263
  • 3
  • 22
  • 40
  • 1
    Yeah, don't turn `--strictFunctionTypes` off unless you really need to. Weird things happen with rest parameters as you've seen, see [microsoft/TypeScript#25749](https://github.com/microsoft/TypeScript/issues/25749) – jcalz Jun 12 '20 at 02:29