TypeScript(v3.2.2)允许我定义接口的并集,每个接口都有一个唯一的字符串文字属性,可以用作类型保护,例如
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 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是限制因素,因此不可能在当前版本的TypeScript中以通用方式定义DeviceOf
。
答案 0 :(得分:2)
知道了。您必须应用两次“ if”,一次创建class Solution {
public boolean checkSubarraySum(int[] nums, int k) {
int curSum=nums[0];
int start=0;
int k1=Math.abs(k);
for(int i=1;i<nums.length;i++){
while (curSum>k1 && start<i-1){
curSum = curSum - nums[start];
start++;
}
if(k1>0 && (curSum%k1)==0){
return true;
}
if(curSum==0 && k1==0){
return true;
}
curSum=curSum+nums[i];
}
return false;
}
类型,第二次检查infer
类型是否扩展了设备。只有在分支infer
中,您才能使用D extends Device
D['type']
答案 1 :(得分:0)
找到了另一种方法,仅使用不带infer
关键字的条件类型:
type FindByType<Union, Type> = Union extends { type: Type } ? Union : never;
type DeviceOf<Type extends Device['type']> = FindByType<Device, Type>;
type Result = DeviceOf<'Laptop'>;
基于Ryan Cavanaugh在这里的评论:https://github.com/Microsoft/TypeScript/issues/17915#issuecomment-413347828