是否有办法使这个TypeScript缩小更少丑陋(或更优雅;-)❓
使用IsSomething类型保护,我希望缩小对任何JavaScript变量的通用方法和属性的访问范围,这些变量不是null,而不是undefined (比如.toString、.valueOf、.hasOwnProperty、.constructor等)。
export type Something =
number | string | boolean | symbol | object | bigint;
export function IsSomething(value: unknown) : value is Something {
return value !== undefined && value !== null;
}
let a = [1, "2", 3];
Narrowing(a);
NotNarrowing(a);
function Narrowing(o: unknown) { // OK
if (IsSomething(o)) {
console.log(o.toString(), o.constructor);
}
}
function NotNarrowing(o: unknown) { // NOT OK
if (o !== null && o !== undefined) {
console.log(o.toString(), o.constructor);
}
}发布于 2022-07-18 02:46:36
在TypeScript中,除null和undefined以外的每个值都可分配给所谓的{}。因此,您可以将您的Something简化为只使用{},并且您的用户定义类型保护功能将与以前一样工作:
export type Something = {};
function isSomething(value: unknown): value is Something {
return value !== undefined && value !== null;
}
function narrowing(o: unknown) { // OK
if (isSomething(o)) {
console.log(o.toString(), o.constructor);
}
}此外,TypeScript 4.8将引入对unknown的改进支持,此后"NotNarrowing“函数将开始工作,因为检查(o !== null && o !== undefined)将自动将o从unknown缩小到{}:
// TS4.8+
function nowNarrowing(o: unknown) { // okay
if (o !== null && o !== undefined) {
console.log(o.toString(), o.constructor);
}
}发布于 2022-07-18 09:07:13
@jcalz的出色回答使我找到了以下解决方案:
// With `IsSomething` type guard, I want to narrow down access
// to common properties of any JS variable
// which is not null and not undefined, like:
// .toString, .valueOf, .hasOwnProperty, .constructor etc.
export function IsSomething(value: unknown) : value is Object {
return value !== null && value !== undefined;
}
Narrowing([1, 2, 3]);
function Narrowing(o: unknown) { // OK
if (IsSomething(o)) {
console.log(o.toString(), o.constructor);
}
}事实证明,TypeScript有一个预定义的interface Object,它的工作方式与我想要的完全一致:

在TypeScript中,Object接口不同于原始object类型,因为前者仍然可以分配给任何其他原语或复杂类型。它也不同于像type Something = {}这样的空类型,因为后者不支持IntelliSense。
// Object interface is OK
let a: Object = 42;
let b: Object = true;
let c: Object = "string";
let d: Object = Symbol(42);
let e: Object = new class SomeClass { someProp = 42 };
// Empty type is OK but no IntelliSense
let a1: {} = 42;
// Error: Type 'number' is not assignable to type 'object'
let a2: object = 42; 操场链接。
一个微妙的问题仍然存在。作为@CertainPerformance 指出,上面的内容不适用于像Object.create(null)这样的边缘情况,在这种情况下,创建的对象没有任何属性或方法,但也不是null。
如果这是一项要求,以下人员应该完成这项工作:
// can be extended to check for toString, valueOf, etc
export function IsSomething(value: unknown) : value is Object {
return (<Object>value)?.constructor !== undefined;
}
Narrowing([1, 2, 3]);
function Narrowing(o: unknown) { // OK
if (IsSomething(o)) {
console.log(o.toString(), o.constructor);
}
}https://stackoverflow.com/questions/73016638
复制相似问题