gpt4 book ai didi

TypeScript:基于字符串文字属性一般推断联合类型成员

转载 作者:行者123 更新时间:2023-12-03 20:16:00 27 4
gpt4 key购买 nike

TypeScript (v3.2.2) 允许我定义接口(interface)的联合,每个接口(interface)都有一个唯一的字符串文字属性,可以用作类型保护,例如

type Device = Laptop | Desktop | Phone;

interface Laptop {
type: 'Laptop';
countDriveBays: number;
hasTouchScreen: boolean;
}

interface Desktop {
type: 'Desktop';
countDriveBays: number;
}

interface Phone {
type: 'Phone';
hasTouchScreen: boolean;
}

function printInfo(device: Device) {
if (device.type === 'Laptop') {
// device: Laptop
console.log(
`A laptop with ${device.countDriveBays} drive bays and ${
device.hasTouchScreen ? 'a' : 'no'
} touchscreen.`,
);
} else if (device.type === 'Desktop') {
// device: Desktop
console.log(`A desktop with ${device.countDriveBays} drive bays.`);
} else {
// device: Phone
console.log(`A phone with ${device.hasTouchScreen ? 'a' : 'no'} touchscreen.`);
}
}

我想写一个函数 isDeviceType以一般方式:

const isDeviceType = <T extends Device['type']>(type: T) => {
return (device: Device): device is DeviceOf<T> => device.type === type;
}

// e.g.
const isPhone = isDeviceType('Phone');
isPhone({ type: 'Phone', hasTouchScreen: true }); // true

但是,我定义 DeviceOf 的方式type 非常冗长,因为它列出了联合中的每一个类型:

type DeviceOf<Type extends Device['type']> =
Type extends Laptop['type'] ? Laptop :
Type extends Desktop['type'] ? Desktop :
Type extends Phone['type'] ? Phone :
never;

有没有更简洁的方式来定义DeviceOf ? 我试过这些:

type DeviceOf<Type extends Device['type']> =
(infer D)['type'] extends Type ? D : never;

// TS2536: Type '"type"' cannot be used to index type 'D'.
// TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type.
// TS6133: 'D' is declared but its value is never read.

type DeviceOf<Type extends Device['type']> =
(infer D) extends Device
? D['type'] extends Type
? D
: never
: never;

// TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type.
// TS6133: 'D' is declared but its value is never read.
// TS2304: Cannot find name 'D'.

我的印象是错误 TS1338 是限制因素,因此无法定义 DeviceOf在当前版本的 TypeScript 中以通用方式。

最佳答案

知道了。您必须应用“if”两次,一次用于创建 infer输入和第二个检查是否 infer类型扩展设备。仅在分支 D extends Device您将可以使用D['type']

type DeviceOf<Type extends Device['type']> =
Device extends (infer D) ?
D extends Device ?
D['type'] extends Type ? D : never : never : never;

type Result = DeviceOf<'Laptop'>;

Playground

关于TypeScript:基于字符串文字属性一般推断联合类型成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54599951/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com