Skip to content

Commit 4989ed0

Browse files
Merge branch 'main' into replace-function-noop
2 parents 839f271 + 2424013 commit 4989ed0

35 files changed

+460
-103
lines changed

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@
6565
"@rollup/plugin-node-resolve": "^15.2.3",
6666
"@rollup/plugin-replace": "^5.0.4",
6767
"@rollup/plugin-terser": "^0.4.4",
68-
"@types/hash-sum": "^1.0.1",
69-
"@types/node": "^20.8.10",
68+
"@types/hash-sum": "^1.0.2",
69+
"@types/node": "^20.9.0",
7070
"@typescript-eslint/parser": "^6.9.1",
7171
"@vitest/coverage-istanbul": "^0.34.6",
7272
"@vue/consolidate": "0.17.3",
@@ -83,7 +83,7 @@
8383
"lodash": "^4.17.21",
8484
"magic-string": "^0.30.5",
8585
"markdown-table": "^3.0.3",
86-
"marked": "^9.1.4",
86+
"marked": "^9.1.5",
8787
"minimist": "^1.2.8",
8888
"npm-run-all": "^4.1.5",
8989
"picocolors": "^1.0.0",

packages/compiler-core/__tests__/transforms/__snapshots__/vModel.spec.ts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ return function render(_ctx, _cache) {
8585
return (_openBlock(), _createElementBlock(\\"input\\", {
8686
\\"foo-value\\": model,
8787
\\"onUpdate:fooValue\\": $event => ((model) = $event)
88-
}, null, 40 /* PROPS, HYDRATE_EVENTS */, [\\"foo-value\\", \\"onUpdate:fooValue\\"]))
88+
}, null, 40 /* PROPS, NEED_HYDRATION */, [\\"foo-value\\", \\"onUpdate:fooValue\\"]))
8989
}
9090
}"
9191
`;

packages/compiler-core/__tests__/transforms/transformElement.spec.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,7 +1089,7 @@ describe('compiler: element transform', () => {
10891089
})
10901090
})
10911091

1092-
test('HYDRATE_EVENTS', () => {
1092+
test('NEED_HYDRATION for v-on', () => {
10931093
// ignore click events (has dedicated fast path)
10941094
const { node } = parseWithElementTransform(`<div @click="foo" />`, {
10951095
directiveTransforms: {
@@ -1108,12 +1108,24 @@ describe('compiler: element transform', () => {
11081108
}
11091109
)
11101110
expect(node2.patchFlag).toBe(
1111-
genFlagText([PatchFlags.PROPS, PatchFlags.HYDRATE_EVENTS])
1111+
genFlagText([PatchFlags.PROPS, PatchFlags.NEED_HYDRATION])
1112+
)
1113+
})
1114+
1115+
test('NEED_HYDRATION for v-bind.prop', () => {
1116+
const { node } = parseWithBind(`<div v-bind:id.prop="id" />`)
1117+
expect(node.patchFlag).toBe(
1118+
genFlagText([PatchFlags.PROPS, PatchFlags.NEED_HYDRATION])
1119+
)
1120+
1121+
const { node: node2 } = parseWithBind(`<div .id="id" />`)
1122+
expect(node2.patchFlag).toBe(
1123+
genFlagText([PatchFlags.PROPS, PatchFlags.NEED_HYDRATION])
11121124
)
11131125
})
11141126

11151127
// #5870
1116-
test('HYDRATE_EVENTS on dynamic component', () => {
1128+
test('NEED_HYDRATION on dynamic component', () => {
11171129
const { node } = parseWithElementTransform(
11181130
`<component :is="foo" @input="foo" />`,
11191131
{
@@ -1123,7 +1135,7 @@ describe('compiler: element transform', () => {
11231135
}
11241136
)
11251137
expect(node.patchFlag).toBe(
1126-
genFlagText([PatchFlags.PROPS, PatchFlags.HYDRATE_EVENTS])
1138+
genFlagText([PatchFlags.PROPS, PatchFlags.NEED_HYDRATION])
11271139
)
11281140
})
11291141
})

packages/compiler-core/src/parse.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1063,7 +1063,7 @@ function parseTextData(
10631063
) {
10641064
return rawText
10651065
} else {
1066-
// DATA or RCDATA containing "&"". Entity decoding required.
1066+
// DATA or RCDATA containing "&". Entity decoding is required.
10671067
return context.options.decodeEntities(
10681068
rawText,
10691069
mode === TextModes.ATTRIBUTE_VALUE

packages/compiler-core/src/transforms/transformElement.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ export function buildProps(
550550
)
551551
} else {
552552
// directives
553-
const { name, arg, exp, loc } = prop
553+
const { name, arg, exp, loc, modifiers } = prop
554554
const isVBind = name === 'bind'
555555
const isVOn = name === 'on'
556556

@@ -678,6 +678,11 @@ export function buildProps(
678678
continue
679679
}
680680

681+
// force hydration for v-bind with .prop modifier
682+
if (isVBind && modifiers.includes('prop')) {
683+
patchFlag |= PatchFlags.NEED_HYDRATION
684+
}
685+
681686
const directiveTransform = context.directiveTransforms[name]
682687
if (directiveTransform) {
683688
// has built-in directive transform.
@@ -743,12 +748,12 @@ export function buildProps(
743748
patchFlag |= PatchFlags.PROPS
744749
}
745750
if (hasHydrationEventBinding) {
746-
patchFlag |= PatchFlags.HYDRATE_EVENTS
751+
patchFlag |= PatchFlags.NEED_HYDRATION
747752
}
748753
}
749754
if (
750755
!shouldUseBlock &&
751-
(patchFlag === 0 || patchFlag === PatchFlags.HYDRATE_EVENTS) &&
756+
(patchFlag === 0 || patchFlag === PatchFlags.NEED_HYDRATION) &&
752757
(hasRef || hasVnodeHook || runtimeDirectives.length > 0)
753758
) {
754759
patchFlag |= PatchFlags.NEED_PATCH

packages/compiler-core/src/transforms/vFor.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ import {
3737
isTemplateNode,
3838
isSlotOutlet,
3939
injectProp,
40-
findDir
40+
findDir,
41+
forAliasRE
4142
} from '../utils'
4243
import {
4344
RENDER_LIST,
@@ -308,7 +309,6 @@ export function processFor(
308309
}
309310
}
310311

311-
const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/
312312
// This regex doesn't cover the case if key or index aliases have destructuring,
313313
// but those do not make sense in the first place, so this works in practice.
314314
const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/

packages/compiler-core/src/utils.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,3 +519,5 @@ export function getMemoedVNodeCall(node: BlockCodegenNode | MemoExpression) {
519519
return node
520520
}
521521
}
522+
523+
export const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/

packages/compiler-dom/__tests__/transforms/stringifyStatic.spec.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,7 @@ describe('stringify static html', () => {
2020
}
2121

2222
function repeat(code: string, n: number): string {
23-
return new Array(n)
24-
.fill(0)
25-
.map(() => code)
26-
.join('')
23+
return code.repeat(n)
2724
}
2825

2926
test('should bail on non-eligible static trees', () => {

packages/compiler-dom/__tests__/transforms/vOn.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ describe('compiler-dom: transform v-on', () => {
272272
// should not treat cached handler as dynamicProp, so it should have no
273273
// dynamicProps flags and only the hydration flag
274274
expect((root as any).children[0].codegenNode.patchFlag).toBe(
275-
genFlagText(PatchFlags.HYDRATE_EVENTS)
275+
genFlagText(PatchFlags.NEED_HYDRATION)
276276
)
277277
expect(prop).toMatchObject({
278278
key: {

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
NodeTypes,
55
SimpleExpressionNode,
66
createRoot,
7+
forAliasRE,
78
parserOptions,
89
transform,
910
walkIdentifiers
@@ -87,8 +88,6 @@ function resolveTemplateUsageCheckString(sfc: SFCDescriptor) {
8788
return code
8889
}
8990

90-
const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/
91-
9291
function processExp(exp: string, dir?: string): string {
9392
if (/ as\s+\w|<.*>|:/.test(exp)) {
9493
if (dir === 'slot') {

packages/compiler-ssr/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export function compile(
7272
// reusing core v-bind
7373
bind: transformBind,
7474
on: transformOn,
75-
// model and show has dedicated SSR handling
75+
// model and show have dedicated SSR handling
7676
model: ssrTransformModel,
7777
show: ssrTransformShow,
7878
// the following are ignored during SSR

packages/dts-test/defineCustomElement.test-d.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
import { defineCustomElement } from 'vue'
2-
import { expectType, describe } from './utils'
1+
import {
2+
defineCustomElement,
3+
defineComponent,
4+
type VueElementConstructor
5+
} from 'vue'
6+
import { expectType, describe, test } from './utils'
37

48
describe('inject', () => {
59
// with object inject
@@ -62,3 +66,20 @@ describe('inject', () => {
6266
}
6367
})
6468
})
69+
70+
describe('defineCustomElement using defineComponent return type', () => {
71+
test('with emits', () => {
72+
const Comp1Vue = defineComponent({
73+
props: {
74+
a: String
75+
},
76+
emits: {
77+
click: () => true
78+
}
79+
})
80+
const Comp = defineCustomElement(Comp1Vue)
81+
expectType<VueElementConstructor>(Comp)
82+
83+
expectType<string | undefined>(new Comp().a)
84+
})
85+
})

packages/dts-test/ref.test-d.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ import {
1515
MaybeRef,
1616
MaybeRefOrGetter,
1717
ComputedRef,
18-
computed
18+
computed,
19+
ShallowRef
1920
} from 'vue'
20-
import { expectType, describe } from './utils'
21+
import { expectType, describe, IsUnion } from './utils'
2122

2223
function plainType(arg: number | Ref<number>) {
2324
// ref coercing
@@ -174,6 +175,27 @@ if (refStatus.value === 'initial') {
174175
refStatus.value = 'invalidating'
175176
}
176177

178+
{
179+
const shallow = shallowRef(1)
180+
expectType<Ref<number>>(shallow)
181+
expectType<ShallowRef<number>>(shallow)
182+
}
183+
184+
{
185+
//#7852
186+
type Steps = { step: '1' } | { step: '2' }
187+
const shallowUnionGenParam = shallowRef<Steps>({ step: '1' })
188+
const shallowUnionAsCast = shallowRef({ step: '1' } as Steps)
189+
190+
expectType<IsUnion<typeof shallowUnionGenParam>>(false)
191+
expectType<IsUnion<typeof shallowUnionAsCast>>(false)
192+
}
193+
194+
describe('shallowRef with generic', <T>() => {
195+
const r = ref({}) as MaybeRef<T>
196+
expectType<ShallowRef<T> | Ref<T>>(shallowRef(r))
197+
})
198+
177199
// proxyRefs: should return `reactive` directly
178200
const r1 = reactive({
179201
k: 'v'

packages/dts-test/setupHelpers.test-d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ describe('defineProps w/ generic type declaration + withDefaults', <T extends
110110
defineProps<{
111111
n?: number
112112
bool?: boolean
113+
s?: string
113114

114115
generic1?: T[] | { x: T }
115116
generic2?: { x: T }
@@ -128,6 +129,10 @@ describe('defineProps w/ generic type declaration + withDefaults', <T extends
128129
)
129130

130131
res.n + 1
132+
// @ts-expect-error should be readonly
133+
res.n++
134+
// @ts-expect-error should be readonly
135+
res.s = ''
131136

132137
expectType<T[] | { x: T }>(res.generic1)
133138
expectType<{ x: T }>(res.generic2)

packages/dts-test/tsx.test-d.tsx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,59 @@ expectType<JSX.Element>(
1717
<div style={[{ color: 'red' }, [{ fontSize: '1em' }]]} />
1818
)
1919

20+
// allow undefined, string, object, array and nested array classes
21+
expectType<JSX.Element>(<div class={undefined} />)
22+
expectType<JSX.Element>(<div class={'foo'} />)
23+
expectType<JSX.Element>(<div class={['foo', undefined, 'bar']} />)
24+
expectType<JSX.Element>(<div class={[]} />)
25+
expectType<JSX.Element>(<div class={['foo', ['bar'], [['baz']]]} />)
26+
expectType<JSX.Element>(<div class={{ foo: true, bar: false, baz: true }} />)
27+
expectType<JSX.Element>(<div class={{}} />)
28+
expectType<JSX.Element>(
29+
<div class={['foo', ['bar'], { baz: true }, [{ qux: true }]]} />
30+
)
31+
expectType<JSX.Element>(
32+
<div
33+
class={[
34+
{ foo: false },
35+
{ bar: 0 },
36+
{ baz: -0 },
37+
{ qux: '' },
38+
{ quux: null },
39+
{ corge: undefined },
40+
{ grault: NaN }
41+
]}
42+
/>
43+
)
44+
expectType<JSX.Element>(
45+
<div
46+
class={[
47+
{ foo: true },
48+
{ bar: 'not-empty' },
49+
{ baz: 1 },
50+
{ qux: {} },
51+
{ quux: [] }
52+
]}
53+
/>
54+
)
55+
56+
// #7955
57+
expectType<JSX.Element>(<div style={[undefined, '', null, false]} />)
58+
59+
expectType<JSX.Element>(<div style={undefined} />)
60+
61+
expectType<JSX.Element>(<div style={null} />)
62+
63+
expectType<JSX.Element>(<div style={''} />)
64+
65+
expectType<JSX.Element>(<div style={false} />)
66+
67+
// @ts-expect-error
68+
;<div style={[0]} />
69+
70+
// @ts-expect-error
71+
;<div style={0} />
72+
2073
// @ts-expect-error unknown prop
2174
;<div foo="bar" />
2275

packages/dts-test/watch.test-d.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ref, computed, watch, defineComponent } from 'vue'
1+
import { ref, computed, watch, defineComponent, shallowRef } from 'vue'
22
import { expectType } from './utils'
33

44
const source = ref('foo')
@@ -92,3 +92,17 @@ defineComponent({
9292
)
9393
}
9494
})
95+
96+
{
97+
//#7852
98+
type Steps = { step: '1' } | { step: '2' }
99+
const shallowUnionGenParam = shallowRef<Steps>({ step: '1' })
100+
const shallowUnionAsCast = shallowRef({ step: '1' } as Steps)
101+
102+
watch(shallowUnionGenParam, value => {
103+
expectType<Steps>(value)
104+
})
105+
watch(shallowUnionAsCast, value => {
106+
expectType<Steps>(value)
107+
})
108+
}

packages/reactivity/src/ref.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,8 @@ export type ShallowRef<T = any> = Ref<T> & { [ShallowRefMarker]?: true }
115115
* @param value - The "inner value" for the shallow ref.
116116
* @see {@link https://vuejs.org/api/reactivity-advanced.html#shallowref}
117117
*/
118-
export function shallowRef<T extends object>(
119-
value: T
120-
): T extends Ref ? T : ShallowRef<T>
118+
export function shallowRef<T>(value: MaybeRef<T>): Ref<T> | ShallowRef<T>
119+
export function shallowRef<T extends Ref>(value: T): T
121120
export function shallowRef<T>(value: T): ShallowRef<T>
122121
export function shallowRef<T = any>(): ShallowRef<T | undefined>
123122
export function shallowRef(value?: unknown) {

packages/runtime-core/__tests__/apiWatch.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ describe('api: watch', () => {
9191
array.push(1)
9292
await nextTick()
9393
expect(spy).toBeCalledTimes(1)
94-
expect(spy).toBeCalledWith([1], expect.anything(), expect.anything())
94+
expect(spy).toBeCalledWith([1], [1], expect.anything())
9595
})
9696

9797
it('should not fire if watched getter result did not change', async () => {

0 commit comments

Comments
 (0)