Skip to content
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

Wrong type parameter inference when there is mapped types and Readonly in the argument type #33164

Closed
ktsn opened this issue Aug 30, 2019 · 2 comments · Fixed by #33223
Closed
Assignees
Labels
Bug A bug in TypeScript Domain: Type Inference Related to type inference performed during signature resolution or `infer` type resolution

Comments

@ktsn
Copy link

ktsn commented Aug 30, 2019

TypeScript Version: 3.6.1-rc, 3.6.2

Search Terms:
mapped types, argument, overload, readonly, intersection

Code

interface Instance {
  _instanceBrand: never
}

type DataDef<Data, Props> = (this: Readonly<Props> & Instance) => Data

type PropsDefinition<T> = {
  [K in keyof T]: T[K]
}

interface Options<
  Data = object | ((this: Instance) => object),
  PropsDef = PropsDefinition<Record<string, any>>
> {
  data?: Data
  props?: PropsDef
  watch?: Record<string, WatchHandler<any>>
}

type WatchHandler<T> = (val: T, oldVal: T) => void;

type ThisTypedOptions<Data, Props> =
  object &
  Options<DataDef<Data, Props>, PropsDefinition<Props>> &
  ThisType<Data & Readonly<Props> & Instance>

declare function test<Data, Props>(fn: ThisTypedOptions<Data, Props>): void;
declare function test(fn: Options): void;

test({
  props: {
    foo: ''
  },

  data(): { bar: boolean } {
    return {
      bar: true
    }
  },

  watch: {
    foo(newVal: string, oldVal: string): void {
      this.bar = false
    }
  }
})

Expected behavior:
No errors. test should choose the first overload.

Actual behavior:
There is an error because the test choose the fallback overload and this is not typed as expected.

Type 'false' is not assignable to type 'WatchHandler<any>'.

If you change the fallback overload's argument type to never, you can see that it wrongly infers Props type parameter in error message.

This will not happen if you do either following things:

  • Replace all appearance of PropsDefinition<XXX> with just XXX (PropsDefinition is just returning the same type but using mapped type)
  • Replace the this type of DataDef (Readonly<Props> & Instance) with Props & Instance

Playground Link:
http://www.typescriptlang.org/play/#code/JYOwLgpgTgZghgYwgAgJIgM5jiJyDeAUMsgPqhY5IBCUOAJgFzIgQBu0hAvoYWAJ4AHFABE42ERBgAeMdgA0yAApQA9oIwA+ZAF5kACjAALYBmYAlCHHqqQAG37SV6rcgBkaTNlwQAlLu05OF4BYWU1DUkYUGAwYFtpABVtPSISAG0AaWRQZABrCH5VGGREgF1mRKyy7l5QSFhEFAB5QTjbDGliZCDdZFUAIwArCAQwZAAfA0MTM09KH38dbUGRsd95budIqT7tjCiY9pBpSwRVKHppLChQAHNFHH5NTUJtNOR6cTgAfmYg7qCCIYP7hFxRboAd3ECCMoLOFyuN3uigA6jCjAAJBh2aDSJ4vWp8IQodFgWHYkD0XFQJIpAxsOB2SqKVR2egANSZlSW2jYqmA9AA3CESaVZokSfRWsdOkFFPsUt1VqNxm5ujL4phZN8ojqFGCNJoFcDDiBYlqnMCXu5uokJST9XB3MhLNZbA4rS5tB50AskK9CPRRnY4FAUDAAK64Y7ISBYJ0m736GAgSoO4TStpauXfJNG3zMfmCkXBhCh8PIKMxrVxiBYFNp5CajqF5DF4UhetgfQfIEuZgfEgwVSqZgAcnH3S4m26X2w+jb+GQAzDzAGo9xOGQXAI3RI4bAkagID3JHPK7XcagkYg+5309nJGh5KMg-vI9U+lYkK5zOQyIgA8-Tsn+zCAXcbYdmeF5xrMAB0q5QH08B2Bgd4XjwJA8FwvhAA
(There is no error on playground as the Ts version is 3.5)

Related Issues:
This is originally reported on Vue.js repo.
vuejs/vue#10455

@weswigham
Copy link
Member

I believe this regressed due to #32558 - #33223 fixes the example given here and should have a build up in it shortly - I'd like to know if it fixes your non-minimized examples.

@weswigham weswigham added the Domain: Type Inference Related to type inference performed during signature resolution or `infer` type resolution label Sep 3, 2019
@ktsn
Copy link
Author

ktsn commented Sep 4, 2019

I just tested #33223 with the Vue's typing and saw the problem is fixed. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Domain: Type Inference Related to type inference performed during signature resolution or `infer` type resolution
Projects
None yet
3 participants