Skip to content

Commit 62000a8

Browse files
committed
Works with vue 2.7.4
1 parent cc38c50 commit 62000a8

7 files changed

+320
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
node_modules/

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"typescript.tsdk": "node_modules/typescript/lib",
3+
}

package-lock.json

Lines changed: 222 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "vue-2-7-issue-typed-emit",
3+
"version": "1.0.0",
4+
"scripts": {
5+
"compile": "tsc --project ./tsconfig.json --noEmit"
6+
},
7+
"author": "Vincent Dallaire <vincent.dallaire@dti.ulaval.ca>",
8+
"license": "MIT",
9+
"devDependencies": {
10+
"typescript": "^4.3.5",
11+
"vue": "^2.7.4",
12+
"vue-class-component": "^7.2.6"
13+
}
14+
}

src/ComponentWithTypedEvents.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import Component from 'vue-class-component';
2+
import VueWithTypedEvents from './VueWithTypedEvents';
3+
4+
export interface ComponentWithTypedEventsEvents {
5+
'event-with-string-payload': string;
6+
'event-with-number-payload': number;
7+
'event-without-payload': undefined;
8+
}
9+
10+
@Component
11+
export default class ComponentWithTypedEvents extends VueWithTypedEvents<ComponentWithTypedEventsEvents> {
12+
emitEventWithStringPayload(): void {
13+
this.$emit('event-with-string-payload', '1');
14+
// this.$emit('event-with-string-payload', 1); // Don't compile. Payload is a number and must be a string.
15+
// this.$emit('event-with-string-payload'); // Don't compile. Payload is undefined and must be defined with a string.
16+
}
17+
18+
emitEventWithNumberPayload(): void {
19+
// this.$emit('event-with-number-payload', '1'); // Don't compile. Payload is a string and must be a number.
20+
this.$emit('event-with-number-payload', 1);
21+
// this.$emit('event-with-number-payload'); // Don't compile. Payload is undefined and must be defined with a number.
22+
}
23+
24+
emitEventWithoutPayload(): void {
25+
// this.$emit('event-without-payload', '1'); // Don't compile. Payload must be undefined.
26+
// this.$emit('event-without-payload', 1); // Don't compile. Payload must be undefined.
27+
this.$emit('event-without-payload');
28+
}
29+
30+
emitEventThatDoesNotExist(): void {
31+
// this.$emit('event-that-does-not-exist'); // Don't compile. Event does not exist on the ComponentWithTypedEventsEvents interface.
32+
}
33+
}

src/VueWithTypedEvents.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
import Vue from 'vue';
3+
import Component from 'vue-class-component';
4+
5+
type IfAny<T, Y, N> = 0 extends (1 & T) ? Y : N;
6+
7+
export default interface VueWithTypedEvents<Events extends Record<string, any> = any> {
8+
$emit<Event extends keyof Events>(
9+
event: Event,
10+
...args: IfAny<Events, any[], Events[Event] extends undefined ? [] : [Events[Event]]>
11+
): this;
12+
}
13+
14+
@Component
15+
export default class VueWithTypedEvents<Events extends Record<string, any> = any> extends Vue {}

tsconfig.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"include": [
3+
"src/*.ts",
4+
],
5+
"compilerOptions": {
6+
"baseUrl": ".",
7+
"lib": [
8+
"es5",
9+
"es6",
10+
"dom",
11+
"scripthost"
12+
],
13+
"target": "es5",
14+
"module": "esnext",
15+
"moduleResolution": "node",
16+
"resolveJsonModule": true,
17+
"experimentalDecorators": true,
18+
"allowSyntheticDefaultImports": true,
19+
"noEmitOnError": true,
20+
"strict": true,
21+
"noFallthroughCasesInSwitch": true,
22+
"noImplicitReturns": true,
23+
"noUnusedLocals": true,
24+
"noUnusedParameters": true,
25+
"noUncheckedIndexedAccess": false,
26+
"sourceMap": true,
27+
"forceConsistentCasingInFileNames": true,
28+
"importsNotUsedAsValues": "remove",
29+
"skipLibCheck": true
30+
}
31+
}

0 commit comments

Comments
 (0)