Typescript: TS2322: inferred string instead value type since TS3.2

Created on 4 Dec 2018  Β·  8Comments  Β·  Source: microsoft/TypeScript


TypeScript Version:

Errors: 3.3.0-dev.20181204, 3.2.1
Works: 3.1.6


Search Terms:

3.2, SFC, React, default, params, value type, string

Code

import * as React from 'react';

type AorB = 'a' | 'b';

type Props1 = {
  aOrB: AorB;
}

type Props2 = {
  aOrB?: AorB;
}

export const Comp1: React.SFC<Props1> = () => null;

export const Comp2: React.SFC<Props2> = ({ aOrB = 'a' }) => <Comp1 aOrB={aOrB} />;
{
  "compilerOptions": {
    "jsx": "react",
    "noEmit": true
  }
}
{
  "name": "ts",
  "version": "1.0.0",
  "license": "MIT",
  "scripts": {
    "type-check": "tsc"
  },
  "devDependencies": {
    "@types/react": "^16.7.13",
    "typescript": "3.x.x"
  }
}

Expected behavior:

For 3.1:

$ yarn type-check
yarn run v1.12.3
$ tsc
✨  Done in 3.62s.

Actual behavior:

For >=3.2:

$ yarn type-check
yarn run v1.12.3
$ tsc
src/index.tsx:15:68 - error TS2322: Type 'string' is not assignable to type 'AorB'.

15 export const Comp2: React.SFC<Props2> = ({ aOrB = 'a' }) => <Comp1 aOrB={aOrB} />;
                                                                      ~~~~

  src/index.tsx:6:3
    6   aOrB: AorB;
        ~~~~
    The expected type comes from property 'aOrB' which is declared here on type 'IntrinsicAttributes & Props1 & { children?: ReactNode; }'


Found 1 error.

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Playground Link:

Related Issues:

Bug Contextual Types Fixed

Most helpful comment

I did further investigation using git bisect and I found https://github.com/Microsoft/TypeScript/commit/4d9a202ef15424d16b723820073b3066d3098351#diff-c3ed224e4daa84352f7f1abcd23e8ccaR4711 introduced this behavior.

All 8 comments

Although I did not test the example published here, I think I have the same problem with a similar setup.

I can also provide an example if that helps (I had to revert to TypeScript 3.1.6, so I need some time to reproduce my problem)

The above snippet compiled successfully in 3.2.0-dev.20181011 but failed in 3.2.0-dev.20181017.
I think the related changes are introduced between these two versions.

Note: we can also use this smaller snippet to reproduce the same error without depending on @types/react.
This snippet also compiles successfully in 3.2.0-dev.20181011 but fails in 3.2.0-dev.20181017.

type MyFunc<P> = (x: P) => void


interface Props {
  n?: 'one' | 'two' | 'three'
}

function oneTwoThree(n: 'one'|'two'|'three') {
  console.log(n)
}

const hello: MyFunc<Props> = ({n = 'one'}) => {
  oneTwoThree(n);
}

hello({});
{
  "compilerOptions": {
    "target": "esnext",
    "module": "commonjs",
    "lib": ["esnext"],
    "noEmit": true,
    "strict": true
  }
}



md5-18751fcd121cf96979e67b93e7893998



index.ts:12:15 - error TS2345: Argument of type 'string' is not assignable to parameter of type '"one" | "two" | "three"'.

12   oneTwoThree(n);
                 ~

I did further investigation using git bisect and I found https://github.com/Microsoft/TypeScript/commit/4d9a202ef15424d16b723820073b3066d3098351#diff-c3ed224e4daa84352f7f1abcd23e8ccaR4711 introduced this behavior.

Hmm... I tried to change the two lines from your commit back to the original state and added tests/cases/compiler/unionTypeWithDefaultParameters.ts:

type MyFunc<P> = (x: P) => void;

interface Props {
  n?: "one" | "two" | "three"
}

function oneTwoThree(n: "one" | "two" | "three") {
  console.log(n);
}

const hello: MyFunc<Props> = ({ n = "one" }) => {
  oneTwoThree(n);
};

hello({});

But AFAIK got still the same error. πŸ€” The jake baseline-accept generated an *.errors.txt with TS2345: Argument of type 'string' is not assignable to parameter of type '"one" | "two" | "three"'..

Really? I also tried it but I could not get the error... πŸ€”
I did the following:

git checkout master
git reset --hard && git clean -xdf # make sure the repo is 'clean'
git revert --no-edit 4d9a202ef15424d16b723820073b3066d3098351

cat > tests/cases/compiler/unionTypeWithDefaultParameters.ts <<EOF
type MyFunc<P> = (x: P) => void;

interface Props {
  n?: "one" | "two" | "three"
}

function oneTwoThree(n: "one" | "two" | "three") {
  console.log(n);
}

const hello: MyFunc<Props> = ({ n = "one" }) => {
  oneTwoThree(n);
};

hello({});
EOF

npm install
./node_modules/.bin/jake local
./node_modules/.bin/jake runtests tests=unionTypeWithDefaultParameters
./node_modules/.bin/jake baseline-accept

And the output of git status was:

On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        tests/baselines/reference/unionTypeWithDefaultParameters.js
        tests/baselines/reference/unionTypeWithDefaultParameters.symbols
        tests/baselines/reference/unionTypeWithDefaultParameters.types
        tests/cases/compiler/unionTypeWithDefaultParameters.ts

nothing added to commit but untracked files present (use "git add" to track)

No *.errors.txt generated πŸ€”

Strange. Probably some error on my side. Thanks for your walkthrough.

@weswigham I think this is a duplicate of #28963 and fixed by #28967.

Yep, I can confirm that #28967 fixes this.

Was this page helpful?
0 / 5 - 0 ratings