关于本节有两点疑问

来源:3-23 高级类型 - 交叉类型

慕莱坞0998854

2020-06-28

1> 假如两个对象有相同的属性名,但是却是不同的类型,那么此时能用交叉类型吗?

	interface A { age: number }
	interface B { age: string}
	const c: A&B = {age:undefined} as A&B

上面的代码不会报错,似乎即使本来不应该存在A&B这样的类型,但是我们还是可以欺骗编译器说有这样的类型

2> Typescript 只负责类型检查,并不管代码逻辑

function extend<T extends object, U extends object>(first: T, second: U): T & U {
  const result = {};
  for (let id in first) {
    (result as T)[id] = first[id];
  }
  for (let id in second) {
    if (!result.hasOwnProperty(id)) {
      (result as U)[id] = second[id];
    }
  }

  return result;
}

这样写,即使我们从逻辑上实现了result是T&U类型的,但是依然会报错。
{}和T&U类型不匹配
但是假如我们并没有实现相应的逻辑,但是定义了相应的类型,代码却不会报错比如

function extend<T extends object, U extends object>(first: T, second: U): T & U {
  const result = {} as T&U;
  return result;
}

const x = extend({ a: 'hello' }, { b: 42 });
x.a // 有相应的代码提示,且不会报错,下同
x.b

我之前还在纠结,这个交叉类型到底包含的是实例上的属性还是类的proptotype上的属性,现在看来,不用管这么多,T&U具体怎么实现你自己来定

写回答

1回答

ustbhuangyi

2020-06-29

1. interface A { age: number }
interface B { age: string}
const c: A&B = {age:undefined} as A&B
这种应该会报错, const c: A & B = { age: 1} as A & B 这样才不会报错。

2. TS 主要是静态语法检查,它是不会管运行时的报错的

extend 可以这么实现

export function extend<T, U>(to: T, from: U): T & U {
 for (const key in from) {
   ;(to as T & U)[key] = from[key] as any
 }
 return to as T & U
}

0
0

下一代前端开发语言 TypeScript从零重构axios

课程从零开始重构功能完整的JS库,是学习造轮子的不二之选!

2631 学习 · 877 问题

查看课程