首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >缩小到TypeScript中常见的JS方法和属性

缩小到TypeScript中常见的JS方法和属性
EN

Stack Overflow用户
提问于 2022-07-18 02:01:39
回答 2查看 75关注 0票数 1

是否有办法使这个TypeScript缩小更少丑陋(或更优雅;-)❓

使用IsSomething类型保护,我希望缩小对任何JavaScript变量的通用方法和属性的访问范围,这些变量不是null,而不是undefined (比如.toString.valueOf.hasOwnProperty.constructor等)。

操场链接

代码语言:javascript
复制
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);
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-07-18 02:46:36

在TypeScript中,除nullundefined以外的每个值都可分配给所谓的{}。因此,您可以将您的Something简化为只使用{},并且您的用户定义类型保护功能将与以前一样工作:

代码语言:javascript
复制
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)将自动将ounknown缩小到{}

代码语言:javascript
复制
// TS4.8+ 
function nowNarrowing(o: unknown) { // okay
  if (o !== null && o !== undefined) {
    console.log(o.toString(), o.constructor);
  }
}

操场链接到代码

票数 2
EN

Stack Overflow用户

发布于 2022-07-18 09:07:13

@jcalz的出色回答使我找到了以下解决方案:

代码语言:javascript
复制
// 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。

代码语言:javascript
复制
// 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

如果这是一项要求,以下人员应该完成这项工作:

代码语言:javascript
复制
// 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);
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73016638

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档