我很难弄清楚如何键入这样的内容:
Fallback
因此,一般而言,此类型采用键FallbackType
及其值类型{[key: Fallback]: FallbackType}
,并创建键值对Partial<FallbackType>
和其他值为的键的字典输入const values = {
base: {
valueA: "baseA",
valueB: "baseB",
},
context1: {
valueA: "context1A",
},
context2: {
valueB: "context2B",
},
};
const useContextValues = <BaseContext extends string, BaseValuesDictionary>(
base: BaseContext,
values: WithFallback<BaseContext, BaseValuesDictionary>,
): BaseValuesDictionary => {
const [activeContext, setContext] = useState<keyof typeof values>(base);
const context = { ...values[base], ...values[activeContext] };
return context;
};
。
它的行为应类似于具有后备(base)值及其变体的字典:
base
这样,在baseA
上下文中,我们的值应等于baseB
中的context1
和contest1A
-在{{ 1}}-baseB
和context2
。
但是,当我期望baseA
返回context2B
= useContextValues
时,它将解析为:
此外,以这种方式传递值时,它解析为其他类型:
我可以以某种方式解决它吗?或者也许根本不起作用?
答案 0 :(得分:0)
听起来不错,最好定义类似于对象传播或Merge
操作的Object.assign
类型:
// Pick own props from T(target) and everything else from U(source, the extending type)
type Merge<T, U> = Omit<T, keyof U> & U
测试:
type T1 = { b: number; a: string }
type S1 = { a: number; c: boolean }
type MergeT1S1 = Merge<T1, S1> // Pick<T1, "b"> & S1
const t: MergeT1S1 = { b: 3, a: 42, c: true } // works
const t2: MergeT1S1 = { b: 3, a: 42 } // error ?
const t3: MergeT1S1 = { b: 3, a: "foo" } // error ?
然后,在Merge
顶部定义一个合并的字典类型:
// you also could further restrict D to constraint "extends WithFallback<K, D[K]>"
type MergedDict<K extends keyof D, D> = {
[P in keyof D]: Merge<D[K], D[P]>
}
...并进行测试:
const values = {
base: {
valueA: "baseA",
},
context1: {
valueA: "context1A",
c: "lala"
}
}
type MergedDict1 = MergedDict<"base", typeof values>
const m: MergedDict1 = { base: { valueA: "foo" }, context1: { valueA: "bar", c: "lala" } } // OK
const m2: MergedDict1 = { base: { valueA: "foo" }, context1: { valueA: "bar" } } // error ?
const m3: MergedDict1 = { base: { valueA: "foo" }, context1: { c: "lala" } } // error ?
最后一步只是调整功能签名useContextValues
:
// set WithFallback as a constraint, not as a type itself for values
declare const useContextValues: <K extends keyof D,
D extends WithFallback<K, D[K]>>(
base: K,
values: D,
) => MergedDict<K, D>
const res = useContextValues("base", values) // should work like above
关于您的错误:
在WithFallback
中,您确实为键fallback
定义了类型变量{ [fallback in Fallback]: FallbackType }
,但是没有使用它来访问属性值。因此TS形成了values
所有可能的prop值的并集类型(如屏幕截图所示)。
为了更正此问题,我们在函数useContextValues
中还将WithFallback
用作类型约束,而不是values
的类型。 WithFallback<K, D[K]>
的意思是,我们传入了像K
这样的基本键"base"
和像D[K]
这样的FallbackType { valueA: "baseA", valueB: "baseB" }
,并且得到了可以定义其他键的基本字典类型(context1
等),其值符合FallbackType。