我编写了一个函数,该函数可以处理传递的是null或未定义的值而不是T,在这种情况下什么也不做,并返回一些默认值。
但是,在许多情况下,编译器很聪明,可以在编译期间知道传入的值不是T或null,而是100%的时间为null,我希望在其中出现编译器错误情况。
示例:
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/fragment"
android:name=".fragments.DataFragment"
tools:layout="@layout/data_fragment"/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activities.MainActivity"
/>
在这种情况下,开发人员不想将null传递给函数并依赖于其默认值,而是使用其他值,但是开发人员混淆了if语句的分支。编译器足够聪明,可以知道obj为null,但是确定的null与null一样有效。
可以做到吗?我正在使用打字稿2.9.2版。可以升级到3。
ps。我在类型系统中寻找解决方案,而不是用“也许单子”对象代替“ T | T”。空值”。
答案 0 :(得分:2)
一定要爱类型的黑客...
const functionThatTakeTheUnionType = <T>(p: T & ([T] extends [null] ? never : T)) => {
// ...
}
参数类型中的第一个T
使推理工作。然后,如果在编译时推断T
肯定是null
,则我们与never
的类型相交,这肯定会导致错误。如果推断T
类似于MyObject | null
,我们将再次与T
相交,这没有任何效果;请注意,由于T | null
已经包含T
(如果适用),因此不必写null
。
答案 1 :(得分:0)
您可以使用重载函数声明,当编译器明确知道参数为null
时,该声明将返回不适当的内容,例如void
:
function functionThatTakeTheUnionType(p: null): void;
function functionThatTakeTheUnionType<T extends { name: string }>(p: T | null): string;
function functionThatTakeTheUnionType<T extends { name: string }>(p: T | null): string {
return p && typeof p.name === 'string' ? p.name : 'default';
}
declare function functionReturningTOrNull(): { name: string } | null;
function a() {
let obj = functionReturningTOrNull();
let name: string;
if (obj === null) {
// error: Type 'void' is not assignable to type 'string'.
name = functionThatTakeTheUnionType(obj)
} else {
name = 'different default name';
}
let obj2 = functionReturningTOrNull();
let name2 = functionThatTakeTheUnionType(obj2); // string
}
但这仅在functionThatTakeTheUnionType
被声明为function
而不是具有功能值的对象的情况下有效。
此外,仅当有人使用functionThatTakeTheUnionType
的结果时,它才会给出错误-我不知道是否有任何方法可以使编译器对其参数产生错误。