]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(types): provide ExtractPublicPropTypes utility type
authorEvan You <yyx990803@gmail.com>
Tue, 2 May 2023 03:06:24 +0000 (11:06 +0800)
committerEvan You <yyx990803@gmail.com>
Tue, 2 May 2023 03:06:32 +0000 (11:06 +0800)
ref #5272
close #8168

packages/compiler-sfc/src/script/resolveType.ts
packages/dts-test/extractProps.test-d.ts [new file with mode: 0644]
packages/dts-test/utils.d.ts
packages/runtime-core/src/componentProps.ts
packages/runtime-core/src/index.ts

index bf29ae089bda6ce541eba337a4a958c0ca8edad6..2fa8d028c653dc1d93dc34b9a60ee2674496883d 100644 (file)
@@ -162,7 +162,8 @@ function innerResolveTypeElements(
     case 'TSTypeReference': {
       const typeName = getReferenceName(node)
       if (
-        typeName === 'ExtractPropTypes' &&
+        (typeName === 'ExtractPropTypes' ||
+          typeName === 'ExtractPublicPropTypes') &&
         node.typeParameters &&
         scope.imports[typeName]?.source === 'vue'
       ) {
diff --git a/packages/dts-test/extractProps.test-d.ts b/packages/dts-test/extractProps.test-d.ts
new file mode 100644 (file)
index 0000000..a40a15e
--- /dev/null
@@ -0,0 +1,30 @@
+import { ExtractPropTypes, ExtractPublicPropTypes } from 'vue'
+import { expectType, Prettify } from './utils'
+
+const propsOptions = {
+  foo: {
+    default: 1
+  },
+  bar: {
+    type: String,
+    required: true
+  },
+  baz: Boolean,
+  qux: Array
+} as const
+
+// internal facing props
+declare const props: Prettify<ExtractPropTypes<typeof propsOptions>>
+
+expectType<number>(props.foo)
+expectType<string>(props.bar)
+expectType<boolean>(props.baz)
+expectType<unknown[] | undefined>(props.qux)
+
+// external facing props
+declare const publicProps: Prettify<ExtractPublicPropTypes<typeof propsOptions>>
+
+expectType<number | undefined>(publicProps.foo)
+expectType<string>(publicProps.bar)
+expectType<boolean | undefined>(publicProps.baz)
+expectType<unknown[] | undefined>(publicProps.qux)
index 790098d962d7185a4c4ad250d78acd6d100532ff..c478b30cb6f921f499a475f83433f940314ed018 100644 (file)
@@ -17,3 +17,5 @@ export type IsUnion<T, U extends T = T> = (
   : true
 
 export type IsAny<T> = 0 extends 1 & T ? true : false
+
+export type Prettify<T> = { [K in keyof T]: T[K] } & {}
index 887ce4f39c6a2fc9640b3e6bea14a143f184f3fc..4d40278955594da08eed1a6c709f6310e7f4a495 100644 (file)
@@ -128,14 +128,42 @@ type InferPropType<T> = [T] extends [null]
     : V
   : T
 
+/**
+ * Extract prop types from a runtime props options object.
+ * The extracted types are **internal** - i.e. the resolved props received by
+ * the component.
+ * - Boolean props are always present
+ * - Props with default values are always present
+ *
+ * To extract accepted props from the parent, use {@link ExtractPublicPropTypes}.
+ */
 export type ExtractPropTypes<O> = {
-  // use `keyof Pick<O, RequiredKeys<O>>` instead of `RequiredKeys<O>` to support IDE features
+  // use `keyof Pick<O, RequiredKeys<O>>` instead of `RequiredKeys<O>` to
+  // support IDE features
   [K in keyof Pick<O, RequiredKeys<O>>]: InferPropType<O[K]>
 } & {
-  // use `keyof Pick<O, OptionalKeys<O>>` instead of `OptionalKeys<O>` to support IDE features
+  // use `keyof Pick<O, OptionalKeys<O>>` instead of `OptionalKeys<O>` to
+  // support IDE features
   [K in keyof Pick<O, OptionalKeys<O>>]?: InferPropType<O[K]>
 }
 
+type PublicRequiredKeys<T> = {
+  [K in keyof T]: T[K] extends { required: true } ? K : never
+}[keyof T]
+
+type PublicOptionalKeys<T> = Exclude<keyof T, PublicRequiredKeys<T>>
+
+/**
+ * Extract prop types from a runtime props options object.
+ * The extracted types are **public** - i.e. the expected props that can be
+ * passed to component.
+ */
+export type ExtractPublicPropTypes<O> = {
+  [K in keyof Pick<O, PublicRequiredKeys<O>>]: InferPropType<O[K]>
+} & {
+  [K in keyof Pick<O, PublicOptionalKeys<O>>]?: InferPropType<O[K]>
+}
+
 const enum BooleanFlags {
   shouldCast,
   shouldCastTrue
index a115b0179c11be951337666c7a502967987e9468..0d5fc39d5f6f20bcae1ecde039cf18f905493c4f 100644 (file)
@@ -254,6 +254,7 @@ export type {
   ComponentPropsOptions,
   ComponentObjectPropsOptions,
   ExtractPropTypes,
+  ExtractPublicPropTypes,
   ExtractDefaultPropTypes
 } from './componentProps'
 export type {