pull/7442/head
Simon Holthausen 3 years ago
parent f1d3b506c5
commit 608cc0e3f3

@ -5,6 +5,7 @@
* **breaking** Minimum supported Node version is now Node 14 * **breaking** Minimum supported Node version is now Node 14
* **breaking** Minimum supported TypeScript version is now 5 (it will likely work with lower versions, but we make no guarantess about that) * **breaking** Minimum supported TypeScript version is now 5 (it will likely work with lower versions, but we make no guarantess about that)
* **breaking** Stricter types for `createEventDispatcher` (see PR for migration instructions) ([#7224](https://github.com/sveltejs/svelte/pull/7224)) * **breaking** Stricter types for `createEventDispatcher` (see PR for migration instructions) ([#7224](https://github.com/sveltejs/svelte/pull/7224))
* **breaking** Stricter types for `Action` and `ActionReturn` (see PR for migration instructions) ([#7224](https://github.com/sveltejs/svelte/pull/7224))
## Unreleased (3.0) ## Unreleased (3.0)

@ -57,6 +57,9 @@ export function onDestroy(fn: () => any) {
} }
export interface EventDispatcher<EventMap extends Record<string, any>> { export interface EventDispatcher<EventMap extends Record<string, any>> {
// Implementation notes:
// - undefined extends X instead of X extends undefined makes this work better with both strict and nonstrict mode
// - [X] extends [never] is needed, X extends never would reduce the whole resulting type to never and not to one of the condition outcomes
<Type extends keyof EventMap>( <Type extends keyof EventMap>(
...args: [EventMap[Type]] extends [never] ? [type: Type, parameter?: null | undefined, options?: DispatchOptions] : ...args: [EventMap[Type]] extends [never] ? [type: Type, parameter?: null | undefined, options?: DispatchOptions] :
null extends EventMap[Type] ? [type: Type, parameter?: EventMap[Type], options?: DispatchOptions] : null extends EventMap[Type] ? [type: Type, parameter?: EventMap[Type], options?: DispatchOptions] :

@ -0,0 +1,148 @@
import type { Action, ActionReturn } from '$runtime/action';
// ---------------- Action
const href: Action<HTMLAnchorElement> = (node) => {
node.href = '';
// @ts-expect-error
node.href = 1;
};
href;
const required: Action<HTMLElement, boolean> = (node, param) => {
node;
param;
};
required(null as any, true);
// @ts-expect-error (only in strict mode) boolean missing
required(null as any);
// @ts-expect-error no boolean
required(null as any, 'string');
const required1: Action<HTMLElement, boolean> = (node, param) => {
node;
param;
return {
update: (p) => p === true,
destroy: () => {}
}
};
required1;
const required2: Action<HTMLElement, boolean> = (node) => {
node;
};
required2;
const required3: Action<HTMLElement, boolean> = (node, param) => {
node;
param;
return {
// @ts-expect-error comparison always resolves to false
update: (p) => p === 'd',
destroy: () => {}
}
};
required3;
const optional: Action<HTMLElement, boolean | undefined> = (node, param?) => {
node;
param;
};
optional(null as any, true);
optional(null as any);
// @ts-expect-error no boolean
optional(null as any, 'string');
const optional1: Action<HTMLElement, boolean | undefined> = (node, param?) => {
node;
param;
return {
update: (p) => p === true,
destroy: () => {}
}
};
optional1;
const optional2: Action<HTMLElement, boolean | undefined> = (node) => {
node;
};
optional2;
const optional3: Action<HTMLElement, boolean | undefined> = (node, param) => {
node;
param;
};
optional3;
const optional4: Action<HTMLElement, boolean | undefined> = (node, param?) => {
node;
param;
return {
// @ts-expect-error comparison always resolves to false
update: (p) => p === 'd',
destroy: () => {}
}
};
optional4;
const no: Action<HTMLElement, never> = (node) => {
node;
};
// @ts-expect-error second param
no(null as any, true);
no(null as any);
// @ts-expect-error second param
no(null as any, 'string');
const no1: Action<HTMLElement, never> = (node) => {
node;
return {
destroy: () => {}
}
};
no1;
// @ts-expect-error param given
const no2: Action<HTMLElement, never> = (node, param?) => {}
// @ts-expect-error param given
const no3: Action<HTMLElement, never> = (node, param) => {}
// @ts-expect-error update method given
const no4: Action<HTMLElement, never> = (node) => {
return {
update: () => {},
destroy: () => {}
}
}
// ---------------- ActionReturn
const requiredReturn: ActionReturn<string> = {
update: (p) => p.toString(),
};
requiredReturn;
const optionalReturn: ActionReturn<boolean | undefined> = {
update: (p) => {
p === true;
// @ts-expect-error could be undefined
p.toString();
},
};
optionalReturn;
const invalidProperty: ActionReturn = {
// @ts-expect-error invalid property
invalid: () => {},
};
invalidProperty;
type Attributes = ActionReturn<never, { a: string; }>['$$_attributes'];
const attributes: Attributes = { a: 'a' };
attributes;
// @ts-expect-error wrong type
const invalidAttributes1: Attributes = { a: 1 };
// @ts-expect-error missing prop
const invalidAttributes2: Attributes = {};
Loading…
Cancel
Save