Subscribe on changes!

could it be bettor for defineProps with typescript only 纯ts定义props希望可以得到进一步优化

avatar
Apr 17th 2023

Vue version

3.3.0-alpha11

Link to minimal reproduction

Steps to reproduce

目前3.3.0 已经支持了从外部导入ts 作为props类型, 但直接使用 市面上的element-plus库二次继承props类型发现还是不能正确运行 也许是需要库也一起升级?
"Currently, version 3.3.0 already supports importing TS as props types from external sources, but we found that directly extending props types from market-available libraries like element-plus may lead to incorrect functionality. Perhaps upgrading the library along with the application is necessary?"

<script setup lang="ts">
import { ElInput } from "element-plus";
type InputProps=InstanceType<typeof ElInput>['$props']
defineProps<InputProps>();
</script>

or

<script setup lang="ts">
import type { InputProps } from "element-plus";
defineProps<InputProps>();
</script>

上面两种情况目前都不能运行 Currently, neither of the two situations mentioned above can run.

What is expected?

希望能支持

type InputProps=InstanceType<typeof ElInput>['$props']
defineProps<InputProps>();  

这种定义类型的方式 作为组件二次封装 如果源组件未能export ts定义 则无法直接使用纯ts 和defineProps的方式来继承props类型 尽管问题不大 但如果能支持更好 "This way of defining types, when used to repackage components, means that directly inheriting props types through pure TS with defineProps is not possible if the source component doesn't export TS definitions. Although this may not be a big issue, being able to support this would be better."

What is actually happening?

类似在react中,如果源组件没有导出props类型, 我们可以用React. ComponentProps 来获取到源组件的类型,从而实现可以二次封装组件 Similar to in React, if the source component doesn't export props types, we can use React.ComponentProps to obtain the type of the source component, thus achieving the ability to repackage components.

import { Button } from "library"; // but doesn't export ButtonProps! oh no!
type ButtonProps = React.ComponentProps<typeof Button>; // no problem! grab your own!
type AlertButtonProps = Omit<ButtonProps, "onClick">; // modify
const AlertButton = (props: AlertButtonProps) => (
  <Button onClick={() => alert("hello")} {...props} />
);

希望defineProps 功能可以更进一步加强 I hope that the defineProps function can be further strengthened.

System Info

No response

Any additional comments?

No response

avatar
Apr 19th 2023

对于使用 ExtractPropTypes 提取出的类型也无法支持

avatar
Apr 20th 2023
  • InstanceType 大概率不会支持,引入的类型复杂度过高。
  • ExtractPropTypes 也不会支持,因为 ExtractPropTypes 意味着你也能拿到运行时 props 定义,直接用那个就行

比如

import type { InputProps } from "element-plus";
defineProps<InputProps>()

这里 InputProps 实际上是 ExtractPropTypes<typeof inputProps>,没有必要绕一圈,直接这样就满足你的需求了:

import { inputProps } from "element-plus";
defineProps(inputProps)
avatar
Apr 20th 2023

@yyx990803 主要是想为了编辑器能够很好的提示, 我有个建议能否 类型和运行时同时存在呢,

<script setup lang="ts">
import { ElInput } from 'element-plus'
import type { InputProps } from 'element-plus'
import MyComponent from '@/components/my-component.vue'

defineProps<Partial<InputProps>>(ElInput.props)
// 或者任意自定义组件,未暴露props类型的
defineProps<InstanceType<typeof MyComponent>>(MyComponent.props)
</script>

这样可以取任意组件的运行时props,但这样编辑器不能准确提示, 如果这时加上ts类型辅助提示,这种写法 ts定义则仅做类型辅助提示用, 就很完美了,

avatar
Apr 20th 2023

如果 ElInput.props 有对应类型,那么 defineProps 也会有类型。你的编辑器没有提示是因为 ElInput.props 是 any,照我的例子用 inputProps 就行了。

avatar
Apr 20th 2023

element-plus 中inputProps为运行时props,InputProps为ts类型props, 但是源码是用了一个build函数 const inputProps = buildProps({ id: { type: String, default: void 0 }, )} 导致不能正确推导 import { inputProps} from "element-plus"; defineProps(inputProps); 看样子是webstorm的问题, vscode可以正确推导 尤大能否联系 webstorm相关团队, webstorm InstanceType typeof ElInput 也推导不了,导致对于script setup的组件 defineExpose的方法 想用父组件调用自组件ref得到的都是any

avatar
Apr 20th 2023

还是希望能支持 props 可以同时支持 运行时props和类型辅助一起写, 有些简单的组件, 如果只在当前.vue文件中定义了props而没有export 出来, 那么外面继承则无法准确推导出来 加入我有一个简单的组件

const props = defineProps<{msg:string}>();

const props = defineProps({
  msg: {
    type: String,
  },
});

如果他 这些定义只在当前文件中而没有export, 那么想继承props并实现类型提示就非常困难了,使用的时候无法得到ts提示

<script setup lang="ts">
import Test from "./test.vue";

defineProps<InstanceType<typeof Test>["$props"]>(Test.props);
</script>

如果能可以用运行时props 的同时添加 ts类型提示, 那这样就能得到很好的提示,而且支持任意组件任意写法了,无论源组件是用的什么写法 @yyx990803