Ich habe ein kniffliges TypeScript-Problem.
Angenommen, ich habe eine Symbolkomponente mit Requisitengröße. Die Größe kann „2“, „4“, „6“ sein. Ich ordne diese Werte einer vordefinierten Rückenwindklasse zu.
Also tippe ich so
type SizeValues = '2' | '4' | '6'; function Icon({size = '4'}: {size: SizeValues}) { const sizeMap = { '2': 'w-2 h-2', '4': 'w-4 h-4', '6': 'w-6 h-6', }; return <span className={sizeMap[size]}>My icon goes here</span> } <Icon size="sm" />
Alles ist in Ordnung. Aber was ist, wenn ich je nach Bildschirmgröße unterschiedliche Größen haben möchte? Deshalb möchte ich versuchen, eine gute Grammatik zu haben, die reibungslos funktioniert.
Also habe ich die Icon-Komponente wie folgt umgeschrieben:
type SizeValues = ??? function Icon({size = '4'}: {size: SizeValues}) { const sizeMap = { '2': 'w-2 h-2', '4': 'w-4 h-4', '6': 'w-6 h-6', 'md:2': 'md:w-2 md:h-2', 'md:4': 'md:w-4 md:h-4', 'md:6': 'md:w-6 md:h-6', 'lg:2': 'lg:w-2 lg:h-2', 'lg:4': 'lg:w-4 lg:h-4', 'lg:6': 'lg:w-6 lg:h-6', }; return <span className={size.split(' ').map(s => sizeMap[s]).join(' ').trim()}>My icon goes here</span> } <Icon size="2 md:4 lg:6" />
Das funktioniert super, aber wie gebe ich es ein? Ich habe gelesen, dass TypeScript in Zukunft reguläre Ausdrücke unterstützen wird. Das wird die Sache einfacher machen, aber kann ich das jetzt eingeben?
Dies ist keine echte Komponente, also machen Sie mir bitte keine guten Vorschläge, wie ich sie verbessern kann. Ich frage mich nur, wie ich mein Größenattribut eingeben soll, damit es so funktioniert, wie ich es codiert habe.
首先,我们需要将
sizeMap
提取到全局范围内,并且 const assert 让编译器知道这是不可变常量并限制它扩大类型:接下来,我们需要获取
sizeMap
的键的类型:实施: 我们将创建一个接受字符串的类型,如果字符串有效则返回该字符串;否则,返回
never
。伪代码:
让类型接受
T
- 要验证的字符串,Original
- 原始字符串,AlreadyUsed
- 已使用键的并集。如果
T
是空字符串返回
原始
否则,如果T
以大小映射 (ClassName
) 的键开头,不包括AlreadyUsed
,后跟一个空格和剩余的字符串(休息
)。递归调用此类型,将
Rest
作为字符串传递以验证Original
,并将AlreadyUsed
与ClassName 添加到其中。
Else if
T
是尺寸映射的键,不包括AlreadyUsed
原始
否则从不
实现:
我们必须向
Item
添加一个通用参数来表示大小
。由于
size
在组件中是可选的,因此我们将在SizeValue
周围添加一个包装器,它将把string | undefined
到string
并将其传递给_SizeValue
,此外我们将为大小添加一个默认值:用法:
游乐场