typescript - 如何判断一个值是否已设置为未定义或根本没有设置?
问题描述
我试图有一个未设置的变量,它的值可以是number
或者undefined
它的默认值是完全未设置的。我想检查它是否未设置,并要求设置它。
使用符号时遇到问题。
const unset = Symbol('undefined')
type nething = number | undefined | typeof unset
type x = Exclude<nething, typeof unset>
function notUnset<T extends typeof unset> (t: T): Exclude<T, typeof unset> {
if (t === unset) throw new Error('is symb')
return t;
}
let value: number | undefined | typeof unset = unset;
value = 1;
const newValue = notUnset(value);
我在使用“TrulyUndefined”类时遇到了问题:
class TrulyUndefined {}
const unset = new TrulyUndefined();
type nething = number | undefined | typeof unset
type x = Exclude<nething, typeof unset>
function notUnset<T extends TrulyUndefined> (t: T): Exclude<T, TrulyUndefined> {
if (t instanceof TrulyUndefined) throw new Error('is symb')
return t;
}
let value: number | undefined | TrulyUndefined = unset;
value = 1;
const newValue = notUnset(value);
有谁知道如何做到这一点?
解决方案
你提到了一个约定,我想知道它是不是可能的单子?
我认为不可能从单个变量中确定一个值是否未设置,因为您已经说过预期的类型T
可以是任何东西,所以我们无法检查一个值是默认值T
还是默认值,因为T
可能包含默认值。
相反,我建议我们有两个值的配对:我们想要的值和一个布尔标志,它告诉我们它是否设置为非。
type MaybeValue<T> = {
value: T;
isSet: true;
} | {
value?: any;
isSet: false;
}
通过将其定义为联合类型,我们强制如果isSet
为真,则该值不能为空。请注意,它可能是undefined
,但前提是T
包括undefined
。
如果isSet
是假的,那么value
可以是任何东西或什么都不是。
这是与此类型交互的示例类。我将这对设置为一个类属性而不是两个,因为它可以很容易地强制执行这两个是可分配给的有效联合MaybeValue<T>
。我还包括了一个getOrElse
受链接文章启发的可链接方法。
class MaybeUnset<T extends any> {
private _maybe: MaybeValue<T>
// constructor creates empty
constructor() {
this._maybe = {
isSet: false
}
}
// static constructor creates with a value already set
public static create<T>( value: T): MaybeUnset<T> {
const obj = new MaybeUnset<T>();
obj.set( value );
return obj;
}
public set( value: T ) {
this._maybe = {
value,
isSet: true
}
}
public unset() {
this._maybe = {
isSet: false
}
}
get isSet(): boolean {
return this._maybe.isSet;
}
public getOrElse<U = T>( fallback: U): T | U {
if ( this._maybe.isSet ) {
return this._maybe.value;
} else {
return fallback;
}
}
}
我希望这是您尝试做的任何事情的坚实起点,但我仍然不完全理解!
推荐阅读
- javascript - 如何更改应用于多个元素中的跨度的类?
- r - opencpu 云的安全配置文件是什么?
- javascript - ESLint 在括号中显示错误
- git - 使用 Github 上具有多个分支的现有 git 存储库
- mysql - 如何通过mysql创建这样的表
- php - 联系表单上下拉菜单的 PHP 代码,基于选择的特定电子邮件
- python - pysqlite 从 csv 文件中获取列名
- scala - 在Scala中反转地图
- sharepoint - 无法再以编程方式访问 SharePoint Online
- kubernetes - 在 Kubernetes 中动态分配端口号?