Skip to content

Commit bff63c5

Browse files
committed
feat(types): provide ExtractPublicPropTypes utility type
ref #5272 close #8168
1 parent 918ec8a commit bff63c5

File tree

5 files changed

+65
-3
lines changed

5 files changed

+65
-3
lines changed

packages/compiler-sfc/src/script/resolveType.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@ function innerResolveTypeElements(
162162
case 'TSTypeReference': {
163163
const typeName = getReferenceName(node)
164164
if (
165-
typeName === 'ExtractPropTypes' &&
165+
(typeName === 'ExtractPropTypes' ||
166+
typeName === 'ExtractPublicPropTypes') &&
166167
node.typeParameters &&
167168
scope.imports[typeName]?.source === 'vue'
168169
) {
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { ExtractPropTypes, ExtractPublicPropTypes } from 'vue'
2+
import { expectType, Prettify } from './utils'
3+
4+
const propsOptions = {
5+
foo: {
6+
default: 1
7+
},
8+
bar: {
9+
type: String,
10+
required: true
11+
},
12+
baz: Boolean,
13+
qux: Array
14+
} as const
15+
16+
// internal facing props
17+
declare const props: Prettify<ExtractPropTypes<typeof propsOptions>>
18+
19+
expectType<number>(props.foo)
20+
expectType<string>(props.bar)
21+
expectType<boolean>(props.baz)
22+
expectType<unknown[] | undefined>(props.qux)
23+
24+
// external facing props
25+
declare const publicProps: Prettify<ExtractPublicPropTypes<typeof propsOptions>>
26+
27+
expectType<number | undefined>(publicProps.foo)
28+
expectType<string>(publicProps.bar)
29+
expectType<boolean | undefined>(publicProps.baz)
30+
expectType<unknown[] | undefined>(publicProps.qux)

packages/dts-test/utils.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,5 @@ export type IsUnion<T, U extends T = T> = (
1717
: true
1818

1919
export type IsAny<T> = 0 extends 1 & T ? true : false
20+
21+
export type Prettify<T> = { [K in keyof T]: T[K] } & {}

packages/runtime-core/src/componentProps.ts

+30-2
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,42 @@ type InferPropType<T> = [T] extends [null]
128128
: V
129129
: T
130130

131+
/**
132+
* Extract prop types from a runtime props options object.
133+
* The extracted types are **internal** - i.e. the resolved props received by
134+
* the component.
135+
* - Boolean props are always present
136+
* - Props with default values are always present
137+
*
138+
* To extract accepted props from the parent, use {@link ExtractPublicPropTypes}.
139+
*/
131140
export type ExtractPropTypes<O> = {
132-
// use `keyof Pick<O, RequiredKeys<O>>` instead of `RequiredKeys<O>` to support IDE features
141+
// use `keyof Pick<O, RequiredKeys<O>>` instead of `RequiredKeys<O>` to
142+
// support IDE features
133143
[K in keyof Pick<O, RequiredKeys<O>>]: InferPropType<O[K]>
134144
} & {
135-
// use `keyof Pick<O, OptionalKeys<O>>` instead of `OptionalKeys<O>` to support IDE features
145+
// use `keyof Pick<O, OptionalKeys<O>>` instead of `OptionalKeys<O>` to
146+
// support IDE features
136147
[K in keyof Pick<O, OptionalKeys<O>>]?: InferPropType<O[K]>
137148
}
138149

150+
type PublicRequiredKeys<T> = {
151+
[K in keyof T]: T[K] extends { required: true } ? K : never
152+
}[keyof T]
153+
154+
type PublicOptionalKeys<T> = Exclude<keyof T, PublicRequiredKeys<T>>
155+
156+
/**
157+
* Extract prop types from a runtime props options object.
158+
* The extracted types are **public** - i.e. the expected props that can be
159+
* passed to component.
160+
*/
161+
export type ExtractPublicPropTypes<O> = {
162+
[K in keyof Pick<O, PublicRequiredKeys<O>>]: InferPropType<O[K]>
163+
} & {
164+
[K in keyof Pick<O, PublicOptionalKeys<O>>]?: InferPropType<O[K]>
165+
}
166+
139167
const enum BooleanFlags {
140168
shouldCast,
141169
shouldCastTrue

packages/runtime-core/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ export type {
254254
ComponentPropsOptions,
255255
ComponentObjectPropsOptions,
256256
ExtractPropTypes,
257+
ExtractPublicPropTypes,
257258
ExtractDefaultPropTypes
258259
} from './componentProps'
259260
export type {

0 commit comments

Comments
 (0)