在Solid.js中正确缩小访问器类型



我有一个Solid.js代码,看起来像这样

import { render } from "solid-js/web";
import { createSignal , Component } from "solid-js";
const Number: Component<{value: number}> = ({value}) => <b>{value}</b> 
const App: Component = () => {
const [foo] = createSignal<number | null>(null);
return (
foo() 
? <Number value={foo()} /> /* foo() is number | null, causing an error */
: <div>foo is null</div>
);
}
render(() => <App />, document.getElementById("app")!);

我如何才能正确地缩小foo()访问器的类型,以便我可以安全地将其传递为Number的道具?

对于普通变量,三元操作符适当地缩小类型:

let bar!: number | null;
bar 
? <Number value={bar} /> // bar's type is narrowed from number | null to number
: <div>bar is null</div>

但是对于访问器变量

似乎不起作用游乐场

您可以使用Show组件来缩小类型

import { render } from "solid-js/web";
import { createSignal, Component, Show } from "solid-js";
const Number: Component<{value: number}> = ({value}) => <b>{value}</b> 
const App: Component = () => {
const [foo] = createSignal<number | null>(null);
return (
<Show when={foo()} fallback={<div>foo is null</div>}>
{(f) => <Number value={f} />}
</Show>
);
}
render(() => <App />, document.getElementById("app")!);

游乐场

缩小类型和呈现值是两个不同的概念。您在三进制中使用的条件不够具体,无法消除非数字值。如果您使用正确的条件,typeof val() === 'number', typescript将正确地计算类型。

const Num: Component<{ value: number }> = (props) => {
return <div>{props.value}</div>
}
const App = () => {
const [val] = createSignal<number | null>(null);
return (
<div>
{typeof val() === 'number' ? <Num value={val()} /> : <div>{val()}</div>}
</div>
);
};

否则,缩小类型的最直接的方法是强制转换,val() as number,但它会抑制给您假阳性的类型。当你知道类型但typescript不能识别时,你应该使用强制类型转换。

可接受答案中的Show组件不会缩小类型范围,而是将when值强制转换为布尔值,并相应地呈现提供的元素。如果你检查它的类型,它是Show<T>,这意味着任何。您正在寻找的是基于值类型的条件呈现。

Solid使用JSX作为其UI层,因此您可以使用表达式有条件地呈现项目,JSX规范中描述的方式:无论您从花括号{}之间的表达式返回什么,都将在屏幕上打印,除非它是一个假值。

您可以使用&&运算符来有条件地呈现元素/组件:

const App = () => {
const myVal = 'two';
return (
<div>
{myVal === 'one' && <div>One</div>}
{myVal === 'two' && <div>One</div>}
{myVal === 'three' && <div>One</div>}
</div>
);
};

可以使用三元操作符在两个元素/组件之间进行选择:

const App = () => {
const isLoggedIn = true;
return (
<div>
{isLoggedIn ? (
<Logout onClick={handleLogout} />
) : (
<Login onClick={handleLogin} />
)}
</div>
);
};

因此,在最基本的方式中,您可以使用typeof运算符来过滤数字仅值:

const App = () => {
const [val] = createSignal<number | null>(0);
return (
<div>
{typeof val() === 'number' ? <div>number: {val()}</div> : <div>Not a number</div>}
</div>
);
};

Solid提供内置的Show组件,用于基于两个互斥条件呈现元素,就像我们使用三元运算符一样。结果将被记忆,以减少下游渲染。

<Show when={true} fallback={<Fallback />}>
<div>My Content</div>
</Show>

它也有一个渲染函数:

<Show when={state.count} fallback={<div>Loading...</div>}>
{(props) => <div>{props.count}</div>}
</Show>

Show组件:

const App = () => {
const [val] = createSignal<number | null>(null);
return (
<Show when={typeof val() === 'number'} fallback={<div>Not a number</div>}>
<div>number: {val()}</div>
</Show>
);
};

也有<Switch>/<Match>根据自定义条件呈现元素:

<Switch fallback={<div>Aww Week Day!</div>}>
<Match when={state.day === "saturday"}>
<Saturday />
</Match>
<Match when={state.day === "sundat"}>
<Sunday />
</Match>
</Switch>

最新更新