有很多关于基于值的条件类型的问题。
但是我不确定下面的场景是否可以实现。
我正在熟悉条件类型,我想知道是否可以创建一个依赖于非空字符串的条件类型。
让我们考虑下一个界面:
interface Animal {
dogName: string;
canBark: boolean;
}
和interface AnimalToBeMapped {
dogsNickname?: string;
/// some other props
}
我正在使用这个接口(interface)来映射一个对象function mapAnimal(animal: AnimalToBeMapped): Animal {
return {
dogName: animal.dogsNickname,
canBark: !animal.dogsNickname
}
}
我正在设置 canBark
属性(property)给 true
仅当参数对象具有 dogName
属性集(也应该适用于空字符串与非空字符串)。我想要做的是为我的
Animal
添加额外的类型安全性。接口(interface)(如果有人手动设置 dogName
来定义,那么我想强制 canBark
属性为 true
,反之亦然)。例子:
const exmpl1: Animal = {
dogName: 'Rex',
canBark: false // I want an error here
}
和const exmpl2: Animal = {
dogName: '',
canBark: true // An error here
}
最佳答案
请让我知道它是否适合您
type NonEmptyString<T extends string> = T extends '' ? never : T;
type WithName = {
dogName: string,
canBark: true,
}
type WithoutName = {
dogName?: '',
canBark: false
};
type Animal = WithName | WithoutName;
type Overloadings =
& ((arg: { canBark: false }) => Animal)
& ((arg: { dogName: '', canBark: false }) => Animal)
& (<S extends string>(arg: { dogName: NonEmptyString<S>, canBark: true }) => Animal)
const animal: Overloadings = (arg: Animal) => {
return arg
}
const x = animal({ dogName: '', canBark: false }) // ok
const xx = animal({ dogName: 'a', canBark: true }) // ok
const xxx = animal({ dogName: 'a', canBark: false }) // error
const xxxx = animal({ dogName: '', canBark: true }) // error
const xxxxx = animal({ canBark: true }) // error
const xxxxxx = animal({ canBark: false }) // ok
PlaygroundTS要区分空字符串和字符串并不是那么容易。输入
string
可分配给文字类型 ''
(空字符串),这就是我使用 NonEmptyString
的原因 helper 更新
如果您对不需要额外功能的更简单的解决方案感兴趣,请参阅以下示例:
type WithName = {
dogName: string,
canBark: true,
}
type WithoutName = {
canBark: false
};
type Animal = WithName | WithoutName;
const x: Animal = {
dogName: 'name',
canBark: true
}; // ok
const xx:Animal={
canBark:false
}; // ok
const xxx:Animal={
canBark:true
} // expected error
const xxxx:Animal={
dogName:''
} // expected error
Playground
关于typescript - 基于非空字符串的条件类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66828502/