Met*_*ian 1 javascript mapping typed-arrays typescript
因此,您有几个强类型的 Map,并且正在构建一个通过迭代来使用它们的 UI,但您可能会根据另一个变量来迭代其中一个或另一个。TypeScript 在奇怪的情况下抱怨类型“从不”。(事实上,TypeScript 一般来说对地图的支持似乎很差)。
考虑这个简化的例子:
let isFirstPicked = false;
const testMap = !isFirstPicked ? MMeasurementType : MMeasurementSize;
const items = [...testMap.keys()].map(
key => key: ${key}, name: ${testMap.get(key).displayName}`
);
console.log(names);
Run Code Online (Sandbox Code Playgroud)
这工作得很好,但是 TypeScript 抱怨
testMap.get(key)
Run Code Online (Sandbox Code Playgroud)
类型为 '"T_SHIRT" | 的参数 “礼服”| “夹克”| “裤子”| “鞋”| “XS”| “S”| “M”| “L”| “XL”| “XXL”不可分配给“never”类型的参数。类型“T_SHIRT”不可分配给类型“never”。ts(2345)
我不喜欢使用“any”,但这会使错误消失:
(testMap as any).get(key)
Run Code Online (Sandbox Code Playgroud)
这是我的打字:
export interface IDisplayName {
displayName: string;
}
export type TMeasurementType =
| "T_SHIRT"
| "DRESS"
| "JACKET"
| "PANTS"
| "SHOES";
export const MMeasurementType = new Map<TMeasurementType, IDisplayName>([
["T_SHIRT", { displayName: "T-Shirts" }],
["DRESS", { displayName: "Dresses" }],
["JACKET", { displayName: "Jackets" }],
["PANTS", { displayName: "Pants" }],
["SHOES", { displayName: "Shoes" }],
]);
export type TMeasurementSize = "XS" | "S" | "M" | "L" | "XL" | "XXL";
export const MMeasurementSize = new Map<TMeasurementSize, IDisplayName>([
["XS", { displayName: "XS" }],
["S", { displayName: "Small" }],
["M", { displayName: "Medium" }],
["L", { displayName: "Large" }],
["XL", { displayName: "XL" }],
["XXL", { displayName: "Double XL" }],
]);
Run Code Online (Sandbox Code Playgroud)
要回答“为什么”问题,请考虑以下内容
interface Phone {
turnOn()
turnOff()
ring()
}
interface Printer {
turnOn()
turnOff()
print()
}
Run Code Online (Sandbox Code Playgroud)
让我们添加一个新类型,它是电话或打印机:
type Device = Phone | Printer
Run Code Online (Sandbox Code Playgroud)
从数学上来说,它是一组电话和一组打印机的并集。这就是为什么它被称为“联合类型”。现在,给定一个 Device 对象,我们可以确定什么?可以打开或关闭吗?当然,因为电话和打印机都可以做到这一点。但可以打印吗?答案通常是否定的,因为它可能恰好是一部手机,但不能。能响吗?同样,答案是否定的,因为它可以是打印机。也就是说,Device 类型仅具有 Phone 和 Printer 通用的方法。这给了我们
有趣的事实#1:复合类型的联合包含它们各部分的交集。
现在考虑:
type FaxMachine = Phone & Printer
Run Code Online (Sandbox Code Playgroud)
这是一个“交叉类型”,代表一个同时是电话和打印机的对象。可以打开/关闭吗?当然。它可以ring?答案是肯定的,因为它是一部电话。它可以print?再说一次,是的,因为它是一台打印机。所以,
有趣的事实#2:复合类型的交集包含它们各部分的并集。
回到地图示例,
type keyA = 'x' | 'y' | 'a'
type keyB = 'x' | 'y' | 'b'
type A = Map<keyA, any>
type B = Map<keyB, any>
type U = A | B
Run Code Online (Sandbox Code Playgroud)
的钥匙是什么类型的U?根据上面的说法,就是keyA & keyB,即'x' | 'y'。如果映射具有不相交的键集,如
type keyA = 'a1' | 'a2'
type keyB = 'b1' | 'b2'
Run Code Online (Sandbox Code Playgroud)
那么 的键的类型U将是一个空集,或者never。
在您的代码中,类型
!isFirstPicked ? MMeasurementType : MMeasurementSize
Run Code Online (Sandbox Code Playgroud)
被推断为
Map<TMeasurementSize, IDisplayName> | Map<TMeasurementType, IDisplayName>
Run Code Online (Sandbox Code Playgroud)
分别,键有类型
TMeasurementSize & TMeasurementType
Run Code Online (Sandbox Code Playgroud)
这是never因为没有交集。
文档:https ://www.typescriptlang.org/docs/handbook/advanced-types.html#intersection-types