You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何区分字符串字面量联合类型?TypeScript CSS API实现疑问

用TypeScript基于MDN元数据实现CSS声明式API的类型问题

我正尝试用MDN元数据结合TypeScript实现CSS样式的声明式API,核心目标是把通用字符串值转换成字符串字面量类型,方便后续生成const文件或者做动态处理。

基础实现示例

下面的基础写法是正常工作的:

const data = [
  { type: 'at-rule', value: '@media' },
  { type: 'css-property', value: 'color' }
]

const createPrefix = <P extends string>(prefix: P) => <A extends string>(it: A) => `${prefix}: ${it};` as `${P}: ${A}`

const color = createPrefix('color') // 正常工作

// 使用示例
const blueText = color('blue')
// 类型推导结果: const blueText: 'color: blue;'

期望的使用场景

理想状态下,希望能生成类似CSSStyleRule的cssText属性格式的字符串字面量,比如链式调用的写法:

import * as s from './composers'

s.of('button-primary').color('blue').background('white')
// 期望输出: .button-primary { color: blue; background: white; }

尝试的代码与困惑

我卡在这个问题上一周了,可能是对TypeScript的类型机制理解不到位。以下是我的尝试代码:

type AtRule =
  | '@color-profile'
  | '@charset'
  | '@counter-style'
  | '@document'
  | '@font-face'
  | '@font-feature-values'
  | '@import'
  | '@property'
  | '@keyframes'
  | '@viewport'
  | '@media'
  | '@namespace'
  | '@page'
  | '@supports'

const createPrefix =
  <A extends AtRule>(a: A) =>
  <B extends string>(b: B) => {
    return `${a}: ${b};` as const
  }

function getComposer<T extends AtRule>(s: T) {
  const value: T = s
  return createPrefix(value)
}

const data = [{ value: '@charset' }, { value: '@document' }] as const

const prefixes = data.map(d => getComposer(d.value))

const something = prefixes[0]('blue')
console.log(something) // 实际运行输出: '@charset: blue;'
// 但TypeScript推导的类型却是: "@charset: blue;" | "@document: blue;"

我忽略了什么?


内容的提问来源于Stack Exchange,提问作者Moa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 08:06:20