vuejs / language-tools

⚡ High-performance Vue language tooling based-on Volar.js
https://marketplace.visualstudio.com/items?itemName=Vue.volar
MIT License
5.76k stars 388 forks source link

prop with conditional type that referencing type param of generic component is simplified in the unwrapped variant for `<template>` #4798

Open n0099 opened 1 week ago

n0099 commented 1 week ago

Vue - Official extension or vue-tsc version

both 2.1.4

VSCode version

1.92.2

Vue version

3.5.0

TypeScript version

5.5.4

System Info

System:
    OS: Windows 11 10.0.22631
    CPU: (4) x64 Intel(R) Core(TM) i5-4200M CPU @ 2.50GHz
    Memory: 8.08 GB / 15.91 GB
  Binaries:
    Node: 22.7.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 4.4.1 - C:\Program Files\nodejs\yarn.CMD
    npm: 10.8.2 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Chromium (127.0.2651.74)
    Internet Explorer: 11.0.22621.3527

package.json dependencies

https://github.com/n0099/open-tbm/blob/8d887a976eb7b2161be592d27c69073f694903b0/fe/package.json

Steps to reproduce

git clone https://github.com/n0099/open-tbm && cd open-tbm
git checkout 8d887a976eb7b2161be592d27c69073f694903b0
cd fe
yarn
sed 's/:postType="props.postType"/:postType="postType"/' src/components/post/badge/Time.vue
yarn vue-tsc

What is expected?

Not reporting as typing of props.postType will narrow the conditional type of timestampType: image but removing props. for postType will simplify timestampType into: image

What is actually happening?

yarn vue-tsc
src/components/post/badge/Time.vue:10:31 - error TS2322: Type '"最后回复时间" | "发帖时间"' is not assignable to type '"发帖时间"'.
  Type '"最后回复时间"' is not assignable to type '"发帖时间"'.

10         :postType="postType" :timestampType="timestampType" v-bind="$attrs">
                                 ~~~~~~~~~~~~~

  src/components/post/badge/TimeView.vue:21:5
    21     timestampType: 'latestReplyPostedAt' extends TPostTimeKey ? '最后回复时间'
           ~~~~~~~~~~~~~
    The expected type comes from property 'timestampType' which is declared here on type '{ current: DateTime<true>; relativeTo?: DateTime<true> | undefined; relativeToText?: string | undefined; postType: "主题帖" | "回复贴" | "楼中楼"; timestampType: "发帖时间"; } & VNodeProps & AllowedComponentProps & ComponentCustomProps'

src/components/post/badge/Time.vue:20:31 - error TS2322: Type '"最后回复时间" | "发帖时间"' is not assignable to type '"发 帖时间"'.
  Type '"最后回复时间"' is not assignable to type '"发帖时间"'.

20         :postType="postType" :timestampType="timestampType" v-bind="$attrs">
                                 ~~~~~~~~~~~~~

  src/components/post/badge/TimeView.vue:21:5
    21     timestampType: 'latestReplyPostedAt' extends TPostTimeKey ? '最后回复时间'
           ~~~~~~~~~~~~~
    The expected type comes from property 'timestampType' which is declared here on type '{ current: DateTime<true>; relativeTo?: DateTime<true> | undefined; relativeToText?: string | undefined; postType: "主题帖" | "回复贴" | "楼中楼"; timestampType: "发帖时间"; } & VNodeProps & AllowedComponentProps & ComponentCustomProps'

src/components/post/badge/Time.vue:31:31 - error TS2322: Type '"最后回复时间" | "发帖时间"' is not assignable to type '"发 帖时间"'.
  Type '"最后回复时间"' is not assignable to type '"发帖时间"'.

31         :postType="postType" :timestampType="timestampType" v-bind="$attrs">
                                 ~~~~~~~~~~~~~

  src/components/post/badge/TimeView.vue:21:5
    21     timestampType: 'latestReplyPostedAt' extends TPostTimeKey ? '最后回复时间'
           ~~~~~~~~~~~~~
    The expected type comes from property 'timestampType' which is declared here on type '{ current: DateTime<true>; relativeTo?: DateTime<true> | undefined; relativeToText?: string | undefined; postType: "主题帖" | "回复贴" | "楼中楼"; timestampType: "发帖时间"; } & VNodeProps & AllowedComponentProps & ComponentCustomProps'

src/components/post/badge/Time.vue:37:6 - error TS2322: Type '"最后回复时间" | "发帖时间"' is not assignable to type '"发帖时间"'.
  Type '"最后回复时间"' is not assignable to type '"发帖时间"'.

37     :timestampType="timestampType" class="text-end"
        ~~~~~~~~~~~~~

  src/components/post/badge/TimeView.vue:21:5
    21     timestampType: 'latestReplyPostedAt' extends TPostTimeKey ? '最后回复时间'
           ~~~~~~~~~~~~~
    The expected type comes from property 'timestampType' which is declared here on type '{ current: DateTime<true>; relativeTo?: DateTime<true> | undefined; relativeToText?: string | undefined; postType: "主题帖" | "回复贴" | "楼中楼"; timestampType: "发帖时间"; } & VNodeProps & AllowedComponentProps & ComponentCustomProps'

Found 4 errors in the same file, starting at: src/components/post/badge/Time.vue:10

Link to minimal reproduction

https://github.com/n0099/open-tbm/blob/8d887a976eb7b2161be592d27c69073f694903b0/fe

Any additional comments?

No response

KazariEX commented 1 week ago

When you directly use postType, its type intersects with the globally defined postType variable. We cannot correctly determine whether it belongs to props to provide better type inference in this situation.