fix: allow $store to be used with changing values including nullish values (#7947)

fixes #7555
breaking change: derived now throws an error if you pass falsy values

---------

Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
pull/8566/head
Ramon Snir 1 year ago committed by GitHub
parent d083f8a3f2
commit ea73930132
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -10,9 +10,11 @@
* **breaking** Stricter types for `onMount` - now throws a type error when returning a function asynchronously to catch potential mistakes around callback functions (see PR for migration instructions) ([#8136](https://github.com/sveltejs/svelte/pull/8136))
* **breaking** Overhaul and drastically improve creating custom elements with Svelte (see PR for list of changes and migration instructions) ([#8457](https://github.com/sveltejs/svelte/pull/8457))
* **breaking** Deprecate `SvelteComponentTyped`, use `SvelteComponent` instead ([#8512](https://github.com/sveltejs/svelte/pull/8512))
* **breaking** Error on falsy values instead of stores passed to `derived` ([#7947](https://github.com/sveltejs/svelte/pull/7947))
* Add `a11y no-noninteractive-element-interactions` rule ([#8391](https://github.com/sveltejs/svelte/pull/8391))
* Add `a11y-no-static-element-interactions`rule ([#8251](https://github.com/sveltejs/svelte/pull/8251))
* Bind `null` option and input values consistently ([#8312](https://github.com/sveltejs/svelte/issues/8312))
* Allow `$store` to be used with changing values including nullish values ([#7555](https://github.com/sveltejs/svelte/issues/7555))
## Unreleased (3.0)

@ -68,6 +68,9 @@ export function validate_store(store, name) {
export function subscribe(store, ...callbacks) {
if (store == null) {
for (const callback of callbacks) {
callback(undefined);
}
return noop;
}
const unsub = store.subscribe(...callbacks);

@ -164,9 +164,10 @@ export function derived<S extends Stores, T>(
export function derived<T>(stores: Stores, fn: Function, initial_value?: T): Readable<T> {
const single = !Array.isArray(stores);
const stores_array: Array<Readable<any>> = single
? [stores as Readable<any>]
: stores as Array<Readable<any>>;
const stores_array: Array<Readable<any>> = single ? [stores as Readable<any>] : stores as Array<Readable<any>>;
if (!stores_array.every(Boolean)) {
throw new Error('derived() expects stores as input, got a falsy value');
}
const auto = fn.length < 2;

@ -0,0 +1,21 @@
import { writable } from '../../../../store';
export default {
html: `
<p>undefined</p>
`,
async test({ assert, component, target }) {
component.store = writable('foo');
assert.htmlEqual(target.innerHTML, `
<p>foo</p>
`);
component.store = undefined;
assert.htmlEqual(target.innerHTML, `
<p>undefined</p>
`);
component.store = writable('bar');
assert.htmlEqual(target.innerHTML, `
<p>bar</p>
`);
}
};

@ -0,0 +1,5 @@
<script>
export let store;
</script>
<p>{$store}</p>

@ -428,6 +428,21 @@ describe('store', () => {
a.set(false);
assert.equal(b_started, false);
});
it('errors on undefined stores #1', () => {
assert.throws(() => {
derived(null, (n) => n);
});
});
it('errors on undefined stores #2', () => {
assert.throws(() => {
const a = writable(1);
derived([a, null, undefined], ([n]) => {
return n * 2;
});
});
});
});
describe('get', () => {

Loading…
Cancel
Save