资讯专栏INFORMATION COLUMN

模拟 vue3.0 rfcs `createComponent` api 中的`props`类型推导

wawor4827 / 2910人阅读

摘要:中类型推导部分预期想实现的效果在中对应的类型是对应的类型是对应的类型是但是,我们想要实现的是转换成小写的所以我们写个泛型来转换预览链接定义的类型留个泛型是给复杂类型做兼容复杂的类型定义函数接收的类型最关键的一步根据输入的类型计算出来函

rfc 中类型推导部分 Type Inference
预期想实现的效果
createComponent({
  props: {
    foo: {
      type: String,
      required: true
    },
    bar: {
      type: Number
    },
    boo: Boolean,
    options: (null as any) as { msg: string },
    requiredOptions: {
      type: (null as any) as { msg: string },
      required: true
    }
  } as const,
  setup(props) {
    props.foo; // string
    props.bar; // number | undefined
    props.boo; // boolean | undefined
    props.options; // {msg: string } | undefined
    props.requiredOptions; // {msg: string }
  }
});
String -> stringNumber -> numberBoolean -> boolean

在 ts 中

String对应的类型是StringConstructor

Number对应的类型是NumberConstructor

Boolean对应的类型是BooleanConstructor

但是,我们想要实现的是转换成小写的string | number | boolean

所以我们写个泛型来转换

type NormalizeType = T extends StringConstructor
  ? string
  : T extends NumberConstructor
  ? number
  : T extends BooleanConstructor
  ? boolean
  : T;

playground 预览链接

定义 prop 的类型
type BuiltInType =
  | StringConstructor
  | NumberConstructor
  | BooleanConstructor
  | T;

留个泛型是给复杂类型做兼容
rfc 复杂的 prop 类型

定义createComponent函数接收的props类型
type DefaultType = {
  [key: string]:
    | {
        type?: BuiltInType;
        require?: boolean;
      }
    | BuiltInType;
};
最关键的一步根据输入的props类型计算出来setup函数接收的形参props类型
type ReflexType = {
  [key in keyof T]: T[key] extends { type: infer TYPE; required: true }
    ? NormalizeType
    : T[key] extends { type: infer TYPE }
    ? NormalizeType | undefined
    : NormalizeType | undefined
};
组合出来createComponent函数定义
function createComponent>(props: {
  props: T;
  setup(props: ReflexType): any;
}) {}
完整代码
type BuiltInType =
  | StringConstructor
  | NumberConstructor
  | BooleanConstructor
  | T;

type NormalizeType = T extends StringConstructor
  ? string
  : T extends NumberConstructor
  ? number
  : T extends BooleanConstructor
  ? boolean
  : T;

type ReflexType = {
  [key in keyof T]: T[key] extends { type: infer TYPE; required: true }
    ? NormalizeType
    : T[key] extends { type: infer TYPE }
    ? NormalizeType | undefined
    : NormalizeType | undefined
};

type DefaultType = {
  [key: string]: { type?: BuiltInType; require?: boolean } | BuiltInType;
};

function createComponent>(props: {
  props: T;
  setup(props: ReflexType): any;
}) {}

createComponent({
  props: {
    foo: {
      type: String,
      required: true
    },
    bar: {
      type: Number
    },
    boo: Boolean,
    options: (null as any) as { msg: string },
    requiredOptions: {
      type: (null as any) as { msg: string },
      required: true
    }
  } as const,
  setup(props) {
    props.foo;
    props.bar;
    props.boo;
    props.options;
    props.requiredOptions;
  }
});

playground 预览链接

效果图

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/104623.html

相关文章

  • 关于Vue2一些值得推荐的文章 -- 五、六月份

    摘要:五六月份推荐集合查看最新的请点击集前端最近很火的框架资源定时更新,欢迎一下。苏幕遮燎沈香宋周邦彦燎沈香,消溽暑。鸟雀呼晴,侵晓窥檐语。叶上初阳乾宿雨,水面清圆,一一风荷举。家住吴门,久作长安旅。五月渔郎相忆否。小楫轻舟,梦入芙蓉浦。 五、六月份推荐集合 查看github最新的Vue weekly;请::点击::集web前端最近很火的vue2框架资源;定时更新,欢迎 Star 一下。 苏...

    sutaking 评论0 收藏0
  • 关于Vue2一些值得推荐的文章 -- 五、六月份

    摘要:五六月份推荐集合查看最新的请点击集前端最近很火的框架资源定时更新,欢迎一下。苏幕遮燎沈香宋周邦彦燎沈香,消溽暑。鸟雀呼晴,侵晓窥檐语。叶上初阳乾宿雨,水面清圆,一一风荷举。家住吴门,久作长安旅。五月渔郎相忆否。小楫轻舟,梦入芙蓉浦。 五、六月份推荐集合 查看github最新的Vue weekly;请::点击::集web前端最近很火的vue2框架资源;定时更新,欢迎 Star 一下。 苏...

    khs1994 评论0 收藏0
  • 精读《Vue3.0 Function API

    摘要:拿到的都是而不是原始值,且这个值会动态变化。精读对于的与,笔者做一些对比。因此采取了作为优化方案只有当第二个依赖参数变化时才返回新引用。不需要使用等进行性能优化,所有性能优化都是自动的。前端精读帮你筛选靠谱的内容。 1. 引言 Vue 3.0 的发布引起了轩然大波,让我们解读下它的 function api RFC 详细了解一下 Vue 团队是怎么想的吧! 首先官方回答了几个最受关注的...

    voyagelab 评论0 收藏0

发表评论

0条评论

wawor4827

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<