Skip to content

Values of string literal type are ignored in generic function #31732

Closed
@maxkomarychev

Description

@maxkomarychev

String literal types are ignored and treated as just "string" when working with generics.

Also the line ("Test 3") which is expectedly fails to compile the error message contains this:

        Type 'number' is not assignable to type '"three" | "four"'.

but actual problem in line "Test 2" seems to ignore this fact

TypeScript Version:

$ tsc --version
Version 3.5.1

Search Terms:

Code

interface PropTypes {
    one: number,
    two: "three"|"four"
}

type ComponentType<P> = (props:P) => any

const MyCompnent = (props: PropTypes) => console.log(props)
MyCompnent({ one: 100, two: "three" })

function decorate<P>(props: P): (Wrapped: ComponentType<P>) => ComponentType<P> {
    return function wrap<P>(Wrapped: ComponentType<P>): ComponentType<P> {
        return (props: P) => console.log({ ...props })
    }
}

// Test 1: should work, all is good
const enhanced1 = decorate({ one: 42, two: "three" })(MyCompnent)
// Test 2: should not work because "two" only allows "three" or "four" as values
const enhanced2 = decorate({ one: 42, two: "wut" })(MyCompnent)
// Test 3: does not work because "two" should be "string", not "number"
const enhanced3 = decorate({ one: 42, two: 111 })(MyCompnent)

Expected behavior:

the following piece of code:

// Test 2: should not work because "two" only allows "three" or "four" as values
const enhanced2 = decorate({ one: 42, two: "wut" })(MyCompnent)

should not be compiled since MyComponent does not allow value "wut" for field "two".

Actual behavior:

Bug.ts:22:51 - error TS2345: Argument of type '(props: PropTypes) => void' is not assignable to parameter of type 'ComponentType<{ one: number; two: number; }>'.
  Types of parameters 'props' and 'props' are incompatible.
    Type '{ one: number; two: number; }' is not assignable to type 'PropTypes'.
      Types of property 'two' are incompatible.
        Type 'number' is not assignable to type '"three" | "four"'.

22 const enhanced3 = decorate({ one: 42, two: 111 })(MyCompnent)

Playground Link:

playground

Related Issues:

Metadata

Metadata

Assignees

Labels

Working as IntendedThe behavior described is the intended behavior; this is not a bug

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions