And*_*dru 0 javascript typescript
这段代码可以很好地有条件地要求该isDirty
字段成为讲座对象的一部分:
id
是 type string
,我必须添加一个isDirty
字段:id
是 type number
,则无法isDirty
向对象添加字段。type LectureT = LectureIdT & {
title: string;
};
/**
* Lecture must have an `isDirty` field if `id` is of type string, but should have no `isDirty` field if `id` if of type number.
*/
type LectureIdT =
| { id: string; isDirty: boolean }
| { id: number; isDirty?: never };
const lectureMockWithNumberId: LectureT = {
id: 1,
title: 'Lecture 1',
// isDirty: false, // Uncomment to see error
};
const lectureMockWithStringId: LectureT = {
id: "1",
title: 'Lecture 2',
isDirty: false,
};
Run Code Online (Sandbox Code Playgroud)
可以在此TS Playground 中使用此代码。
问题:为什么我需要问号isDirty?: never
?
我对此事的调查:
当我删除问号isDirty?: never
以获取isDirty: never
它不再起作用时:
type LectureIdT =
| { id: string; isDirty: boolean }
| { id: number; isDirty: never };
Run Code Online (Sandbox Code Playgroud)
lectureMockWithNumberId
突然有一个打字稿错误:
Type '{ id: number; title: string; }' is not assignable to type 'LectureT'.
Type '{ id: number; title: string; }' is not assignable to type '{ id: number; isDirty: never; } & { title: string; }'.
Property 'isDirty' is missing in type '{ id: number; title: string; }' but required in type '{ id: number; isDirty: never; }'.
Run Code Online (Sandbox Code Playgroud)
我们在最后一句话中看到它说这isDirty
是必需的。但这对我来说似乎不对!它的类型是never
-> 所以它永远不是必需的,不是吗?
为什么我必须添加一个问号才能使其工作。这似乎不合逻辑。
为了理解它,我将其更改为isDirty: never | undefined
:
type LectureIdT =
| { id: string; isDirty: boolean }
| { id: number; isDirty: never | undefined };
Run Code Online (Sandbox Code Playgroud)
但令我惊讶的是,错误仍然存在!不是?
in ega?: string
等于a: string | undefined
吗?
我不明白...
?
在这里首先是必要的,而且isDirty: never;
基本上是不可能的。?
当它与 一起使用时表现不同never
?让我一一回答这些问题:
我们在最后一句话中看到它说这
isDirty
是必需的。但这对我来说似乎不对!它的类型是never
-> 所以它永远不是必需的,不是吗?
never
就其与可选对象属性的交互方式而言,该类型没有任何独特之处。你可以认为never
是相同的任何其他类型的(string
,number,
等等)。不同之处在于,与这些其他类型不同,没有可分配给 的值never
。你可能会说一个类型的变量never
“永远”不能被赋予一个有效的值。
但令我惊讶的是,错误仍然存在!不是
?
in ega?: string
等于a: string | undefined
吗?
不。考虑两个对象之间的区别:{}
和{a: undefined}
。在一种情况下,钥匙完全丢失了。在另一个中它存在并具有值undefined
。前一个对象可分配给{a?: string}
但不能分配给{a: string | undefined}
。
这将导致:
为什么问号
?
在这里首先是必要的,而且isDirty: never;
基本上是不可能的。
像上面的例子一样,如果你没有?
在键名上包含,那么类型中需要键。关键只是有存在。但是该键的值的类型是never
. 因此,您无法为该键分配有效值。
所以简而言之,没有问号确实是不可能的,因为它是一个矛盾的要求:那个键必须存在,但没有值对其有效。
最后:
为什么
?
当它与never
.
这仅仅是 的通常属性never
与 的通常行为相结合的结果?
。这两个特定功能的交互没有什么特别之处。
使用 的示例{isDirty?: never}
,这意味着以下条件之一必须为真:
isDirty
关键。isDirty
键并且它的值是 type never
。由于这两种情况中的第二种是不可能的(根据上述参数),所以只剩下第一种情况:匹配此类型的对象不得包含isDirty
键。