-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
chore:Update for TS7 #16485
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
chore:Update for TS7 #16485
Changes from 3 commits
55367b3
3de210e
f8bf282
84b50a6
c2f5e05
5d567f3
03ee9b9
47ce6af
ea56403
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'svelte': patch | ||
--- | ||
|
||
Update for TS7 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -55,7 +55,7 @@ export function convert(source, ast) { | |
|
||
// Insert svelte:options back into the root nodes | ||
if (/** @type {any} */ (options)?.__raw__) { | ||
let idx = node.fragment.nodes.findIndex((node) => options.end <= node.start); | ||
let idx = node.fragment.nodes.findIndex((node) => /** @type {any} */ (options).end <= node.start); | ||
|
||
if (idx === -1) { | ||
idx = node.fragment.nodes.length; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,8 +9,8 @@ import { | |
import { regex_ends_with_whitespace, regex_starts_with_whitespace } from '../../patterns.js'; | ||
import { get_attribute_chunks, is_text_attribute } from '../../../utils/ast.js'; | ||
|
||
/** @typedef {NODE_PROBABLY_EXISTS | NODE_DEFINITELY_EXISTS} NodeExistsValue */ | ||
/** @typedef {FORWARD | BACKWARD} Direction */ | ||
/** @typedef {typeof NODE_PROBABLY_EXISTS | typeof NODE_DEFINITELY_EXISTS} NodeExistsValue */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. JS type annotations no longer insert |
||
/** @typedef {typeof FORWARD | typeof BACKWARD} Direction */ | ||
|
||
const NODE_PROBABLY_EXISTS = 0; | ||
const NODE_DEFINITELY_EXISTS = 1; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ export default function check_graph_for_cycles(edges) { | |
}, new Map()); | ||
|
||
const visited = new Set(); | ||
/** @type {Set<T>} */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
const on_stack = new Set(); | ||
/** @type {Array<Array<T>>} */ | ||
const cycles = []; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -160,10 +160,14 @@ export function createEventDispatcher() { | |
e.lifecycle_outside_component('createEventDispatcher'); | ||
} | ||
|
||
/** | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same: signature-to-signature checking (like when you're checking that a returned function has the right type) is stricter in TS7, so you have to explicitly note that I also improved the cast on type but I can't remember if that's actually necessary. |
||
* @param [detail] | ||
* @param [options] | ||
*/ | ||
return (type, detail, options) => { | ||
const events = /** @type {Record<string, Function | Function[]>} */ ( | ||
active_component_context.s.$$events | ||
)?.[/** @type {any} */ (type)]; | ||
)?.[/** @type {string} */ (type)]; | ||
|
||
if (events) { | ||
const callbacks = is_array(events) ? events.slice() : [events]; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,7 +64,7 @@ export function hmr(original, get_source) { | |
// @ts-expect-error | ||
wrapper[FILENAME] = original[FILENAME]; | ||
|
||
// @ts-expect-error | ||
// @ts-ignore | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The error being ignored here is bogus, a result of wonky JS checking that mistakenly causes a circularity. In TS7, this bug is fixed. If this were a complete upgrade to TS7, I would remove this line, but since I want it to compile on TS5 and TS7, I switched it to ts-ignore. |
||
wrapper[HMR] = { | ||
// When we accept an update, we set the original source to the new component | ||
original, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,8 @@ const PENDING = 0; | |
const THEN = 1; | ||
const CATCH = 2; | ||
|
||
/** @typedef {typeof PENDING | typeof THEN | typeof CATCH} AwaitState */ | ||
|
||
/** | ||
* @template V | ||
* @param {TemplateNode} node | ||
|
@@ -67,9 +69,8 @@ export function await_block(node, get_input, pending_fn, then_fn, catch_fn) { | |
: mutable_source(/** @type {V} */ (undefined), false, false); | ||
var error_source = runes ? source(undefined) : mutable_source(undefined, false, false); | ||
var resolved = false; | ||
|
||
/** | ||
* @param {PENDING | THEN | CATCH} state | ||
* @param {AwaitState} state | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here; |
||
* @param {boolean} restore | ||
*/ | ||
function update(state, restore) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -191,7 +191,7 @@ export function each(node, flags, get_collection, get_key, render_fn, fallback_f | |
// store a reference to the effect so that we can update the start/end nodes in reconciliation | ||
each_effect ??= /** @type {Effect} */ (active_effect); | ||
|
||
array = get(each_array); | ||
array = /** @type {V[]} */ (get(each_array)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
var length = array.length; | ||
|
||
if (was_empty && length === 0) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
/** @import { Equals } from '#client' */ | ||
|
||
/** @type {Equals} */ | ||
export function equals(value) { | ||
export const equals = function(value) { | ||
|
||
return value === this.v; | ||
} | ||
|
||
|
@@ -26,6 +26,6 @@ export function not_equal(a, b) { | |
} | ||
|
||
/** @type {Equals} */ | ||
export function safe_equals(value) { | ||
export const safe_equals = function(value) { | ||
return !safe_not_equal(value, this.v); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -184,8 +184,7 @@ export function legacy_rest_props(props, exclude) { | |
* The proxy handler for spread props. Handles the incoming array of props | ||
* that looks like `() => { dynamic: props }, { static: prop }, ..` and wraps | ||
* them so that the whole thing is passed to the component as the `$$props` argument. | ||
* @template {Record<string | symbol, unknown>} T | ||
* @type {ProxyHandler<{ props: Array<T | (() => T)> }>}} | ||
* @type {ProxyHandler<{ props: Array<Record<string | symbol, unknown> | (() => Record<string | symbol, unknown>)> }>}} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
*/ | ||
const spread_props_handler = { | ||
get(target, key) { | ||
|
@@ -362,8 +361,7 @@ export function prop(props, key, flags, fallback) { | |
// means we can just call `$$props.foo = value` directly | ||
if (setter) { | ||
var legacy_parent = props.$$legacy; | ||
|
||
return function (/** @type {any} */ value, /** @type {boolean} */ mutation) { | ||
return /** @type {() => V} */ (function (/** @type {V} */ value, /** @type {boolean} */ mutation) { | ||
|
||
if (arguments.length > 0) { | ||
// We don't want to notify if the value was mutated and the parent is in runes mode. | ||
// In that case the state proxy (if it exists) should take care of the notification. | ||
|
@@ -377,7 +375,7 @@ export function prop(props, key, flags, fallback) { | |
} | ||
|
||
return getter(); | ||
}; | ||
}); | ||
} | ||
|
||
// Either prop is written to, but there's no binding, which means we | ||
|
@@ -399,8 +397,8 @@ export function prop(props, key, flags, fallback) { | |
if (bindable) get(d); | ||
|
||
var parent_effect = /** @type {Effect} */ (active_effect); | ||
|
||
return function (/** @type {any} */ value, /** @type {boolean} */ mutation) { | ||
return /** @type {() => V} */(function (/** @type {any} */ value, /** @type {boolean} */ mutation) { | ||
if (arguments.length > 0) { | ||
const new_value = mutation ? get(d) : runes && bindable ? proxy(value) : value; | ||
|
||
|
@@ -424,5 +422,5 @@ export function prop(props, key, flags, fallback) { | |
} | ||
|
||
return get(d); | ||
}; | ||
}); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -284,7 +284,8 @@ export function update_reaction(reaction) { | |
|
||
try { | ||
reaction.f |= REACTION_IS_UPDATING; | ||
var result = /** @type {Function} */ (0, reaction.fn)(); | ||
var fn = /** @type {Function} */ (reaction.fn); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typescript errors on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The To me it looks more like maybe this was the intended type: var result = (0, /** @type {Function} */ (reaction.fn))(); And this is an example why it matters: const reaction = {
location: "House",
fn() {
console.log("this", this);
return `Hello from ${this.location}!`;
}
};
// 'this' is acting on globalThis/window now
const result = (0, reaction.fn)();
// Hint: not "House"
console.log("result", result); |
||
var result = fn(); | ||
var deps = reaction.deps; | ||
|
||
if (new_deps !== null) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,7 +35,7 @@ export function validate_store(store, name) { | |
} | ||
|
||
/** | ||
* @template {() => unknown} T | ||
* @template {(...args: any[]) => unknown} T | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. JS arity checking between signatures is lax in TS5 so it didn't catch this. |
||
* @param {T} fn | ||
*/ | ||
export function prevent_snippet_stringification(fn) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,9 @@ import { raf as svelte_raf } from 'svelte/internal/client'; | |
import { queue_micro_task } from '../src/internal/client/dom/task.js'; | ||
|
||
export const raf = { | ||
/** @type {Set<Animation>} */ | ||
animations: new Set(), | ||
/** @type {Set<(n: number) => void>} */ | ||
ticks: new Set(), | ||
tick, | ||
time: 0, | ||
|
@@ -54,14 +56,24 @@ class Animation { | |
|
||
/** | ||
* @param {HTMLElement} target | ||
* @param {Keyframe[]} keyframes | ||
* @param {{ duration: number, delay: number }} options | ||
* @param {Keyframe[] | PropertyIndexedKeyframes | null} keyframes | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I kind of went overboard here fixing up this test to handle the DOM types. It's probably better to turn a bunch of these types to |
||
* @param {number | KeyframeAnimationOptions | undefined} options | ||
*/ | ||
constructor(target, keyframes, { duration, delay }) { | ||
constructor(target, keyframes, options) { | ||
this.target = target; | ||
this.#keyframes = keyframes; | ||
this.#duration = Math.round(duration); | ||
this.#delay = delay ?? 0; | ||
this.#keyframes = Array.isArray(keyframes) ? keyframes : []; | ||
if (typeof options === 'number') { | ||
this.#duration = options; | ||
this.#delay = 0; | ||
} else { | ||
const { duration = 0, delay = 0 } = options ?? {}; | ||
if (typeof duration === 'object') { | ||
this.#duration = 0; | ||
} else { | ||
this.#duration = Math.round(+duration); | ||
} | ||
this.#delay = delay; | ||
} | ||
|
||
this._update(); | ||
} | ||
|
@@ -189,13 +201,15 @@ function interpolate(a, b, p) { | |
* @param {{duration: number, delay: number}} options | ||
* @returns {globalThis.Animation} | ||
*/ | ||
// @ts-ignore | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the location of the error to be ignored moved in TS7 to match the location reported in a .ts file |
||
HTMLElement.prototype.animate = function (keyframes, options) { | ||
const animation = new Animation(this, keyframes, options); | ||
raf.animations.add(animation); | ||
// @ts-ignore | ||
return animation; | ||
}; | ||
|
||
// @ts-ignore | ||
HTMLElement.prototype.getAnimations = function () { | ||
return Array.from(raf.animations).filter((animation) => animation.target === this); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,6 +43,7 @@ export function create_deferred() { | |
/** @param {any} [reason] */ | ||
let reject = (reason) => {}; | ||
|
||
/** @type {Promise<any>} */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TS7 inferred |
||
const promise = new Promise((f, r) => { | ||
resolve = f; | ||
reject = r; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pkg.imports: any
andObject.entries
now infers[string, unknown]
instead of[string, any]
. This is stricter, and what happens in .ts files, but requires an explicit param type.This shows up quite a bit in this PR.