Typescript 是否可以检测不必要的类型防护装置?

Typescript 是否可以检测不必要的类型防护装置?,typescript,static-analysis,Typescript,Static Analysis,我有以下类型脚本代码: type Nothing = undefined | null; export const isNothing = <T>(val: T | Nothing): val is Nothing => val === null || typeof val === 'undefined'; 这里的情况是类型保护是冗余的。由于foo是显式键入的,因此它不能是null或未定义的 我一直试图从以下几方面找到答案: 如果val不是联合类型,则重载isNothi

我有以下类型脚本代码:

type Nothing = undefined | null;
export const isNothing = <T>(val: T | Nothing): val is Nothing =>
  val === null || typeof val === 'undefined';
这里的情况是类型保护是冗余的。由于
foo
是显式键入的,因此它不能是
null
未定义的

我一直试图从以下几方面找到答案:

  • 如果
    val
    不是联合类型,则重载
    isNothing
    返回类型
    never
  • 一些linter规则,用于标记接受联合的函数的参数何时不是联合(这感觉像是一种大锤式方法)
  • 某些linter规则显式检测不必要的类型保护

在这种情况下,“检测”可能是编译时错误或linter通知。重要的是,这将是一个运行前检测。

正如我在上面的注释中所解释的,如果检查是冗余的,则类型保护本身不会阻止代码编译。我认为术语“类型联合”是指在这种特殊情况下,一个非空且未定义的变量,因此
isNothing
类型保护检查是多余的

解决方案是在调用
isNothing
类型保护之前,强制编译器检查变量是否“可能为null或未定义”:

type Nothing = undefined | null;

export const isNothing = <T>(val: T | Nothing): val is Nothing =>
  val === null || typeof val === 'undefined';


let a!: number;
let b!: number | undefined;
let c!: undefined;
let d!: null;

function assertMaybeNothing<T extends (Exclude<T, Exclude<T, undefined | null>> extends never ? never : any)>(arg1: T) {
  return true;
}

assertMaybeNothing(a); // error because is never undefined or null
assertMaybeNothing(b);
assertMaybeNothing(c);
assertMaybeNothing(d);

if (assertMaybeNothing(a) && isNothing(a)) {
  let x = a;// is never
} 

type Nothing=undefined | null;
导出常量为Nothing=(val:T | Nothing):val为Nothing=>
val===null | | typeof val===“未定义”;
让我来数量;
让b!:编号|未定义;
让c!:未定义;
让d!:无效的
函数assertMaybeNothing(arg1:T){
返回true;
}
资产可不包括(a);//错误,因为从未定义过或为null
资产可能不存在(b);
资产可能不存在(c);
资产可能不存在(d);
如果(资产可能无(a)项和无(a)项){
设x=a;//永远不是
} 

我最终选择了这个:

type Nothing = undefined | null;

export function isNothing<T>(val: NonNullable<T>): never
export function isNothing<T>(val: T | Nothing): val is Nothing
export function isNothing<T>(val: T) { return val === null || typeof val === 'undefined'; }
type Nothing=undefined | null;
导出函数isNothing(val:NonNullable):从不
导出函数为Nothing(val:T | Nothing):val为Nothing
导出函数为Nothing(val:T){return val==null | | typeof val==='undefined';}
然后,在TSLint配置中将
严格布尔表达式设置为
true


因此,每当显式类型的变量(不包含
null
undefined
的变量)被传递到此函数时,我的linter就会捕获。

检测的结果应该是什么?@user2864740令人敬畏的问题-我已经更新以澄清我的意思是“运行前”,通过
tslint
tsc
您对
重载
的确切含义是什么,以便类型保护返回
从不
?类型保护必须返回布尔值。到第二个要点:也许你指的是作为参数的交叉点类型,那么所有传递的类型都必须满足指定的约束。@iY1NQ,所以,我在四处寻找探索的途径。通过“重载”,我的意思是,如果函数被传递为非联合类型,签名将返回
never
,这将导致我的代码中出现错误(这正是我想要的)。。。我不认为那条路会是平坦的fruitful@iY1NQ至于“也许你指的是作为参数的交叉口类型”,我不确定你指的是什么。。。归根结底,这是一个类型后卫,所以它需要一个联盟,对吗?
type Nothing = undefined | null;

export function isNothing<T>(val: NonNullable<T>): never
export function isNothing<T>(val: T | Nothing): val is Nothing
export function isNothing<T>(val: T) { return val === null || typeof val === 'undefined'; }