let o1 = { a: 1, b: 'a' };
if ('k' in o1) {
// 此处 o1 的类型 发生了 & 运算
// { a: number; b: string } & { k: unknown }
console.log(o1)
}
type Word = string & "abc";
// 用户自定义类型守卫: 用于分支流程中
function isString(v: any): v is string {
// v is string 这个部分 是 类型谓词签名(type predicates signatures)
// https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates
// 在后续的上下文中 v 的类型会是 typeof v & string
return typeof v === 'string';
}
// 用户自定义类型守卫函数: 用于顺序流程中
function assertIsNumber(v: any):asserts v is number {
// asserts v is number 这个部分 是 断言签名(assertion signatures)
// 在后续的上下文中 v 的类型会是 typeof v & number
if (typeof v === 'number') {
return void 0;
}
throw Error('not a number')
}
let a!: string;
let b!: string | number;
b = "a";
if (isString(b)) {
type BT = typeof b;
// ^?
// type BT = string
}
// 此时 b 为 string
assertIsNumber(b);
// 断言签名
a = b;
// 可辨识联合类型
interface AA {
id: 'aa'
a: string
}
interface BB {
id: "bb"
b: number
}
interface CC {
id: "cc"
c: boolean
}
type ABC = AA | BB | CC;
let abc!: ABC;
if (abc.id === "aa") {
type Tep = typeof abc;
// ^?
// type Tep = AA
} else if (abc.id === "bb") {
type Tep = typeof abc;
// ^?
// type Tep = BB
} else {
type Tep = typeof abc;
// ^?
// type Tep = CC
}
// 疑问: type MyKey = Omit<string, 'abc'>; 这个类型收窄的 结果为什么会是 string; 是因为 string 集合 和 移除 abc 的 string 集合 在类型系统中基本没有区别吗?
展开
作者回复: 1、你的示例与你的问题没关系。方便的话,建议你回头将问题单列。
2、Omit<>不能操作string,Omit处理的是接口而不是基础类型。因此事实上你得到的是Omit<string as String, ...>的结果。
3、Omit<>操作string as String的细节要讨论到第19讲,才会籍由keyof操作来说明。——不过本课程中没有讲,只是这个问题涉及到keyof而已。^^.