Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

feat(types): support inferring attrs #7444

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 20 commits into
base: minor
Choose a base branch
Loading
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
chore: improve code
  • Loading branch information
rudyxu1102 committed Oct 27, 2023
commit 091559ac720e53b2be34822a48a72ad97f3eecf1
118 changes: 59 additions & 59 deletions 118 packages/dts-test/defineComponent.test-d.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
Slots,
VNode
} from 'vue'
import { describe, expectType, IsUnion } from './utils'
import { describe, expectType, IsUnion, test } from './utils'

describe('with object props', () => {
interface ExpectedProps {
Expand Down Expand Up @@ -1195,18 +1195,16 @@ describe('define attrs', () => {
bar: number
baz?: string
}
const MyComp = defineComponent(
{
props: {
foo: String
},
attrs: Object as AttrsType<CompAttrs>,
created() {
expectType<CompAttrs['bar']>(this.$attrs.bar)
expectType<CompAttrs['baz']>(this.$attrs.baz)
}
const MyComp = defineComponent({
props: {
foo: String
},
attrs: Object as AttrsType<CompAttrs>,
created() {
expectType<CompAttrs['bar']>(this.$attrs.bar)
expectType<CompAttrs['baz']>(this.$attrs.baz)
}
)
})
expectType<JSX.Element>(<MyComp foo="1" bar={1} />)
})

Expand All @@ -1215,16 +1213,14 @@ describe('define attrs', () => {
bar: number
baz?: string
}
const MyComp = defineComponent(
{
props: ['foo'],
attrs: Object as AttrsType<CompAttrs>,
created() {
expectType<CompAttrs['bar']>(this.$attrs.bar)
expectType<CompAttrs['baz']>(this.$attrs.baz)
}
const MyComp = defineComponent({
props: ['foo'],
attrs: Object as AttrsType<CompAttrs>,
created() {
expectType<CompAttrs['bar']>(this.$attrs.bar)
expectType<CompAttrs['baz']>(this.$attrs.baz)
}
)
})
expectType<JSX.Element>(<MyComp foo="1" bar={1} />)
})

Expand All @@ -1233,15 +1229,13 @@ describe('define attrs', () => {
bar: number
baz?: string
}
const MyComp = defineComponent(
{
attrs: Object as AttrsType<CompAttrs>,
created() {
expectType<CompAttrs['bar']>(this.$attrs.bar)
expectType<CompAttrs['baz']>(this.$attrs.baz)
}
const MyComp = defineComponent({
attrs: Object as AttrsType<CompAttrs>,
created() {
expectType<CompAttrs['bar']>(this.$attrs.bar)
expectType<CompAttrs['baz']>(this.$attrs.baz)
}
)
})
expectType<JSX.Element>(<MyComp bar={1} />)
})

Expand All @@ -1250,24 +1244,20 @@ describe('define attrs', () => {
bar: number
baz?: string
}
const MyComp = defineComponent(
{
props: {
foo: {
type: String,
required: true
}
},
setup(props, { attrs }) {
expectType<string>(props.foo)
expectType<number>(attrs.bar)
expectType<string | undefined>(attrs.baz)
const MyComp = defineComponent({
props: {
foo: {
type: String,
required: true
}
},
{
attrs: {} as CompAttrs
attrs: Object as AttrsType<CompAttrs>,
setup(props, { attrs }) {
expectType<string>(props.foo)
expectType<number>(attrs.bar)
expectType<string | undefined>(attrs.baz)
}
)
})
expectType<JSX.Element>(<MyComp foo="1" bar={1} />)
})

Expand All @@ -1283,11 +1273,10 @@ describe('define attrs', () => {
expectType<CompAttrs['baz']>(ctx.attrs.baz)
return () => (
// return a render function (both JSX and h() works)
<div>
{props.foo}
</div>
<div>{props.foo}</div>
)
}, {
},
{
attrs: Object as AttrsType<CompAttrs>
}
)
Expand All @@ -1298,20 +1287,31 @@ describe('define attrs', () => {
type CompAttrs = {
foo: number
}
const MyComp = defineComponent(
{
props: {
foo: String
},
attrs: Object as AttrsType<CompAttrs>,
created() {
// @ts-expect-error
console.log(this.$attrs.foo)
}
const MyComp = defineComponent({
props: {
foo: String
},
attrs: Object as AttrsType<CompAttrs>,
created() {
// @ts-expect-error
console.log(this.$attrs.foo)
}
)
})
expectType<JSX.Element>(<MyComp foo="1" />)
})

test('define attrs w/ no attrs', () => {
const MyComp = defineComponent({
props: {
foo: String
},
created() {
expectType<unknown>(this.$attrs.bar)
}
})
// @ts-expect-error
expectType<JSX.Element>(<MyComp foo="1" bar={1} />)
})
})

// #5948
Expand Down
87 changes: 35 additions & 52 deletions 87 packages/dts-test/defineCustomElement.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import {
defineCustomElement,
expectType,
expectError,
SetupContext
} from './index'
import { defineCustomElement, AttrsType } from 'vue'
import { describe, expectType, test } from './utils'

describe('inject', () => {
// with object inject
Expand Down Expand Up @@ -73,57 +69,45 @@ describe('define attrs', () => {
bar: number
baz?: string
}
defineCustomElement(
{
props: {
foo: String
},
created() {
expectType<number>(this.$attrs.bar)
expectType<string | undefined>(this.$attrs.baz)
}
defineCustomElement({
props: {
foo: String
},
{
attrs: {} as CompAttrs
attrs: Object as AttrsType<CompAttrs>,
created() {
expectType<number>(this.$attrs.bar)
expectType<string | undefined>(this.$attrs.baz)
}
)
})
})

test('define attrs w/ array props', () => {
type CompAttrs = {
bar: number
baz?: string
}
defineCustomElement(
{
props: ['foo'],
created() {
expectType<number>(this.$attrs.bar)
expectType<string | undefined>(this.$attrs.baz)
}
},
{
attrs: {} as CompAttrs
defineCustomElement({
props: ['foo'],
attrs: Object as AttrsType<CompAttrs>,
created() {
expectType<number>(this.$attrs.bar)
expectType<string | undefined>(this.$attrs.baz)
}
)
})
})

test('define attrs w/ no props', () => {
type CompAttrs = {
bar: number
baz?: string
}
defineCustomElement(
{
created() {
expectType<number>(this.$attrs.bar)
expectType<string | undefined>(this.$attrs.baz)
}
},
{
attrs: {} as CompAttrs
defineCustomElement({
attrs: Object as AttrsType<CompAttrs>,
created() {
expectType<number>(this.$attrs.bar)
expectType<string | undefined>(this.$attrs.baz)
}
)
})
})

test('define attrs w/ function component', () => {
Expand All @@ -132,10 +116,13 @@ describe('define attrs', () => {
baz?: string
}
defineCustomElement(
(_props: { foo: string }, ctx: SetupContext<{}, CompAttrs>) => {
(_props: { foo: string }, ctx) => {
expectType<number>(ctx.attrs.bar)
expectType<number>(ctx.attrs.bar)
expectType<string | undefined>(ctx.attrs.baz)
},
{
attrs: Object as AttrsType<CompAttrs>
}
)
})
Expand All @@ -144,19 +131,15 @@ describe('define attrs', () => {
type CompAttrs = {
foo: number
}
defineCustomElement(
{
props: {
foo: String
},
created() {
// @ts-expect-error
console.log(this.$attrs.foo)
}
defineCustomElement({
props: {
foo: String
},
{
attrs: {} as CompAttrs
attrs: Object as AttrsType<CompAttrs>,
created() {
// @ts-expect-error
console.log(this.$attrs.foo)
}
)
})
})
})
19 changes: 12 additions & 7 deletions 19 packages/runtime-core/src/apiDefineComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
import {
SetupContext,
AllowedComponentProps,
ComponentCustomProps
ComponentCustomProps,
Data
} from './component'
import {
ExtractPropTypes,
Expand All @@ -28,7 +29,8 @@ import { extend, isFunction } from '@vue/shared'
import { VNodeProps } from './vnode'
import {
CreateComponentPublicInstance,
ComponentPublicInstanceConstructor
ComponentPublicInstanceConstructor,
IsSameType
} from './componentPublicInstance'
import { SlotsType } from './componentSlots'

Expand Down Expand Up @@ -57,7 +59,7 @@ export type DefineComponent<
Props = ResolveProps<PropsOrPropOptions, E>,
Defaults = ExtractDefaultPropTypes<PropsOrPropOptions>,
S extends SlotsType = {},
Attrs extends AttrsType = {},
Attrs extends AttrsType = {}
> = ComponentPublicInstanceConstructor<
CreateComponentPublicInstance<
Props,
Expand Down Expand Up @@ -107,7 +109,10 @@ export function defineComponent<
E extends EmitsOptions = {},
EE extends string = string,
S extends SlotsType = {},
Attrs extends AttrsType = {}
Attrs extends AttrsType = {},
PropsAttrs = IsSameType<Data, UnwrapAttrsType<Attrs>> extends true
? {}
: UnwrapAttrsType<Attrs>
>(
setup: (
props: Props,
Expand All @@ -116,10 +121,10 @@ export function defineComponent<
options?: Pick<ComponentOptions, 'name' | 'inheritAttrs'> & {
props?: (keyof Props)[]
emits?: E | EE[]
slots?: S,
slots?: S
attrs?: Attrs
}
): (props: Props & EmitsToProps<E> & UnwrapAttrsType<Attrs>) => any
): (props: Props & EmitsToProps<E> & PropsAttrs) => any
export function defineComponent<
Props extends Record<string, any>,
E extends EmitsOptions = {},
Expand Down Expand Up @@ -153,7 +158,7 @@ export function defineComponent<
S extends SlotsType = {},
Attrs extends AttrsType = {},
I extends ComponentInjectOptions = {},
II extends string = string,
II extends string = string
>(
comp: ComponentOptionsWithoutProps<
Props,
Expand Down
4 changes: 1 addition & 3 deletions 4 packages/runtime-core/src/componentOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,9 +428,7 @@ export type UnwrapAttrsType<
? Data
: Readonly<
Prettify<{
[K in keyof T]: NonNullable<T[K]> extends (...args: any[]) => any
? T[K]
: T[K]
[K in keyof T]: T[K]
}>
>

Expand Down
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.