如何在TypeScript中接受仅为5的倍数的数字?

svmlkihl  于 2022-12-24  发布在  TypeScript
关注(0)|答案(2)|浏览(146)

我不确定这是否可行,但我很好奇,所以提出了这个问题。我正在构建一个组件,其中包含一个正方形图像,该图像包含一个size属性。我希望强制size值始终是5的倍数,以便图像保持清晰。
我对这个主题的贫乏知识使我想到了这个,但并没有真正按照我预期的方式工作。

type Props = {
  size: (x) => (x % 5 === 0)
};

在一天结束的时候,我只想能够在我使用 prop 的时候检查它们。例如:

// TS should throw an error
<Logo size={32} />

// TS should allow it
<Logo size={40} />

用TypeScript可以实现这样的功能吗?

cu6pst1q

cu6pst1q1#

非常非常有趣的问题和TS在这里闪耀:))从4. 1开始,你可以有这个例子。
因为所有5的乘数都以0或5结尾,所以可以这样求解

type EndsWithZeroOrFive = '0' | '5'
type OtherDigits = `${number}` | ''
type MultiplierOfFive = `${OtherDigits}${EndsWithZeroOrFive}`

const n1 : MultiplierOfFive = '10' 
const n2 : MultiplierOfFive = '25' 
// no issue

const n3 : MultiplierOfFive = '12' 
// Type '"12"' is not assignable to type 'EndsWithZeroOrFive | `${number}0` | `${number}5`'.
uurity8g

uurity8g2#

可以验证数字:

type ZeroOrFive = '0' | '5'

type IsValid<N extends number> = `${N}` extends '5' | `${number}${ZeroOrFive}` ? N : never

type Result = IsValid<5> // 5

const fn = <Num extends number>(num: IsValid<Num>) => num

fn(10) // ok
fn(5) // ok
fn(125) // ok

fn(11) // Error
fn(0) // Error
fn(NaN) // Error
fn(Infinity) // Error
fn(05) // Error
fn('05') // Error

const higherOrder = (num: number) => fn(num); // error with higher order function

Playground
诀窍在于使用带泛型参数的条件类型。
如果您对泛型参数的验证感兴趣,可以查看我的文章herehere

相关问题