typescript - 基于非空字符串的条件类型

标签 typescript

有很多关于基于值的条件类型的问题。
但是我不确定下面的场景是否可以实现。
我正在熟悉条件类型,我想知道是否可以创建一个依赖于非空字符串的条件类型。
让我们考虑下一个界面:

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
Playground
TS要区分空字符串和字符串并不是那么容易。输入 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/

相关文章:

javascript - 继承方法调用触发 Typescript 编译器错误

javascript - 使用字符串键和 JQuery 值动态创建关联数组

typescript - 使用 Prisma ORM 检索日期(仅)列作为字符串或映射到字符串而无需时间

typescript 提示数组解构后的变量类型

macos - 如何在 mac os x 上安装旧版本的 TypeScript?

Angular 2 :ngModel cannot be used to register form controls with a parent formGroup directive

javascript - 如何为 Angular Material Slide Toggle 设置默认值?

typescript - 我可以在 TypeScript lambda 中访问另一个吗?

javascript - 为什么 TypeScript 报告 "' string' is not assignable to type 'RequestMode' "?

Angular Ivy 类型检查 : Type 'SafeHtml' is not assignable to type 'string'