Skip to content

Commit

Permalink
chore: improve code
Browse files Browse the repository at this point in the history
  • Loading branch information
rudyxu committed Sep 1, 2023
1 parent ba3b8b9 commit b8d6793
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 108 deletions.
91 changes: 43 additions & 48 deletions packages/dts-test/defineComponent.test-d.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1191,14 +1191,13 @@ describe('async setup', () => {

describe('define attrs', () => {
test('define attrs w/ object props', () => {
type CompAttrs = {
bar: number
}
const MyComp = defineComponent({
props: {
foo: String
},
attrs: Object as AttrsType<CompAttrs>,
attrs: Object as AttrsType<{
bar?: number
}>,
created() {
expectType<number | undefined>(this.$attrs.bar)
}
Expand All @@ -1207,12 +1206,11 @@ describe('define attrs', () => {
})

test('define attrs w/ array props', () => {
type CompAttrs = {
bar: number
}
const MyComp = defineComponent({
props: ['foo'],
attrs: Object as AttrsType<CompAttrs>,
attrs: Object as AttrsType<{
bar?: number
}>,
created() {
expectType<number | undefined>(this.$attrs.bar)
}
Expand All @@ -1221,11 +1219,10 @@ describe('define attrs', () => {
})

test('define attrs w/ no props', () => {
type CompAttrs = {
bar: number
}
const MyComp = defineComponent({
attrs: Object as AttrsType<CompAttrs>,
attrs: Object as AttrsType<{
bar?: number
}>,
created() {
expectType<number | undefined>(this.$attrs.bar)
}
Expand All @@ -1234,17 +1231,16 @@ describe('define attrs', () => {
})

test('define attrs w/ composition api', () => {
type CompAttrs = {
bar: number
}
const MyComp = defineComponent({
props: {
foo: {
type: String,
required: true
}
},
attrs: Object as AttrsType<CompAttrs>,
attrs: Object as AttrsType<{
bar?: number
}>,
setup(props, { attrs }) {
expectType<string>(props.foo)
expectType<number | undefined>(attrs.bar)
Expand All @@ -1254,9 +1250,6 @@ describe('define attrs', () => {
})

test('define attrs w/ functional component', () => {
type CompAttrs = {
bar: number
}
const MyComp = defineComponent(
(props: { foo: string }, ctx) => {
expectType<number | undefined>(ctx.attrs.bar)
Expand All @@ -1266,61 +1259,46 @@ describe('define attrs', () => {
)
},
{
attrs: Object as AttrsType<CompAttrs>
attrs: Object as AttrsType<{
bar?: number
}>
}
)
expectType<JSX.Element>(<MyComp foo={'1'} bar={1} />)
})

test('define attrs as low priority', () => {
type CompAttrs = {
foo: number
}
const MyComp = defineComponent({
props: {
foo: String
},
attrs: Object as AttrsType<CompAttrs>,
attrs: Object as AttrsType<{
foo?: number
}>,
created() {
// @ts-expect-error
this.$attrs.foo

expectType<string | undefined>(this.foo);
}
})
expectType<JSX.Element>(<MyComp foo="1" />)
})

test('attrs is always optional w/ object props', () => {
type CompAttrs = {
bar: number
}
test('define required attrs', () => {
const MyComp = defineComponent({
attrs: Object as AttrsType<CompAttrs>,
attrs: Object as AttrsType<{
bar: number
}>,
created() {
expectType<number | undefined>(this.$attrs.bar)
}
})
expectType<JSX.Element>(<MyComp bar={1}/>)
// @ts-expect-error
expectType<JSX.Element>(<MyComp />)
})

test('attrs is always optional w/ functional component', () => {
type CompAttrs = {
bar: number
}
const MyComp = defineComponent(
(props: { foo: string }, ctx) => {
expectType<number | undefined>(ctx.attrs.bar)
return () => (
// return a render function (both JSX and h() works)
<div>{props.foo}</div>
)
},
{
attrs: Object as AttrsType<CompAttrs>
}
)
expectType<JSX.Element>(<MyComp foo={'1'} />)
})

test('define attrs w/ no attrs', () => {
const MyComp = defineComponent({
props: {
Expand All @@ -1333,6 +1311,23 @@ describe('define attrs', () => {
// @ts-expect-error
expectType<JSX.Element>(<MyComp foo="1" bar={1} />)
})

test('default attrs like class, style', () => {
const MyComp = defineComponent({
props: {
foo: String
},
attrs: Object as AttrsType<{
bar?: number
}>,
created() {
expectType<number | undefined>(this.$attrs.bar)
expectType<unknown>(this.$attrs.class)
expectType<unknown>(this.$attrs.style)
}
})
expectType<JSX.Element>(<MyComp class={'str'} style={'str'} foo="1" bar={1} />)
})
})

// #5948
Expand Down
80 changes: 40 additions & 40 deletions packages/dts-test/defineCustomElement.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,80 +65,54 @@ describe('inject', () => {

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

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

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

test('define attrs w/ function component', () => {
type CompAttrs = {
bar: number
baz?: string
}
defineCustomElement(
(_props: { foo: string }, ctx) => {
expectType<number | undefined>(ctx.attrs.bar)
expectType<number | undefined>(ctx.attrs.bar)
expectType<string | undefined>(ctx.attrs.baz)
},
{
attrs: Object as AttrsType<CompAttrs>
}
)
})

test('define attrs as low priority', () => {
type CompAttrs = {
foo: number
}
defineCustomElement({
props: {
foo: String
foo: String,
},
attrs: Object as AttrsType<CompAttrs>,
attrs: Object as AttrsType<{
foo: number
}>,
created() {
// @ts-expect-error
this.$attrs.foo
expectType<string | undefined>(this.foo)
}
})
})
Expand All @@ -154,4 +128,30 @@ describe('define attrs', () => {
}
})
})

test('default attrs like class, style', () => {
defineCustomElement({
props: {
foo: String
},
created() {
expectType<unknown>(this.$attrs.class)
expectType<unknown>(this.$attrs.style)
}
})
})

test('define required attrs', () => {
defineCustomElement({
props: {
foo: String
},
attrs: Object as AttrsType<{
bar: number
}>,
created() {
expectType<number>(this.$attrs.bar)
}
})
})
})
4 changes: 2 additions & 2 deletions packages/runtime-core/src/apiDefineComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ export function defineComponent<
props?: (keyof Props)[]
emits?: E | EE[]
slots?: S
attrs?: Partial<Attrs>
attrs?: Attrs
}
): (props: Props & EmitsToProps<E> & Partial<PropsAttrs>) => any
): (props: Props & EmitsToProps<E> & PropsAttrs) => any
export function defineComponent<
Props extends Record<string, any>,
E extends EmitsOptions = {},
Expand Down
6 changes: 2 additions & 4 deletions packages/runtime-core/src/componentPublicInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ export type ComponentPublicInstance<
Attrs extends AttrsType = {},
PropsAttrs = IsSameType<UnwrapAttrsType<Attrs>, Data> extends true
? {}
: Partial<Omit<UnwrapAttrsType<Attrs>, keyof (P & PublicProps)>>
: Omit<UnwrapAttrsType<Attrs>, keyof (P & PublicProps)>
> = {
$: ComponentInternalInstance
$data: D
Expand All @@ -227,10 +227,8 @@ export type ComponentPublicInstance<
? Partial<Defaults> & Omit<P & PublicProps, keyof Defaults> & PropsAttrs
: P & PublicProps & PropsAttrs
>
$attrs: Partial<
Omit<UnwrapAttrsType<Attrs>, keyof (P & PublicProps)> &
$attrs: Omit<UnwrapAttrsType<Attrs>, keyof (P & PublicProps)> &
AllowedComponentProps
>
$refs: Data
$slots: UnwrapSlotsType<S>
$root: ComponentPublicInstance | null
Expand Down
9 changes: 4 additions & 5 deletions packages/runtime-core/src/vnode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ import {
ConcreteComponent,
ClassComponent,
Component,
isClassComponent,
AllowedComponentProps
isClassComponent
} from './component'
import { RawSlots } from './componentSlots'
import { isProxy, Ref, toRaw, ReactiveFlags, isRef } from '@vue/reactivity'
Expand Down Expand Up @@ -817,7 +816,7 @@ export function normalizeChildren(vnode: VNode, children: unknown) {
vnode.shapeFlag |= type
}

export function mergeProps(...args: (AllowedComponentProps | Data)[]) {
export function mergeProps(...args: (Data & VNodeProps)[]) {
const ret: Data = {}
for (let i = 0; i < args.length; i++) {
const toMerge = args[i]
Expand All @@ -830,7 +829,7 @@ export function mergeProps(...args: (AllowedComponentProps | Data)[]) {
ret.style = normalizeStyle([ret.style, toMerge.style])
} else if (isOn(key)) {
const existing = ret[key]
const incoming = (toMerge as Data)[key]
const incoming = toMerge[key]
if (
incoming &&
existing !== incoming &&
Expand All @@ -841,7 +840,7 @@ export function mergeProps(...args: (AllowedComponentProps | Data)[]) {
: incoming
}
} else if (key !== '') {
ret[key] = (toMerge as Data)[key]
ret[key] = toMerge[key]
}
}
}
Expand Down
Loading

0 comments on commit b8d6793

Please sign in to comment.