所以我有一个格式为
{ 'type': type }
的类型映射,并想在通用函数中使用它来“动态”确定返回类型,但是它不起作用。
代码如下:
// Using type instead of interface. I believe it doesn't make any difference?
type SupportedPropertyTypes = {
string: string,
number: number,
boolean: boolean,
object: any
}
type PropertyType = keyof SupportedPropertyTypes
type PropertyDefinition<T extends PropertyType, N = false> = {
type: T,
nullable?: N,
fallback?: PropertyValue<T,N> | (() => PropertyValue<T,N>)
}
type StorageConfig = {
namespace: string,
properties: {
[key: string]: PropertyDefinition<PropertyType>
}
}
type PropertyValue<T extends PropertyType, N = false> = SupportedPropertyTypes[T]
| (() => SupportedPropertyTypes[T])
| (N extends true ? null : never)
const config = {
namespace: 'foo',
properties: {
foo: { type: 'string' },
bar: { type: 'number', fallback: 1338 },
baz: { type: 'boolean', nullable: true },
complicatedThing: {
type: 'object',
nullable: true,
fallback: () => ({
foo: 'bar',
bar: 'baz',
arr: [1,2],
})
}
}
}
function getFallback<TProps extends StorageConfig['properties'], T extends keyof TProps> (key: T, props: TProps) {
return typeof props[key].fallback == 'function'
? props[key].fallback()
: props[key].fallback
}
// Expected: const foo: { foo: string, bar: string, arr: number[] }
// Got: error
const foo = getFallback('complicatedThing', config.properties)
这里出现错误:
Argument of type '{ foo: { type: string; }; bar: { type: string; fallback: number; }; baz: { type: string; nullable: boolean; }; complicatedThing: { type: string; nullable: boolean; fallback: () => { foo: string; bar: string; arr: number[]; }; }; }' is not assignable to parameter of type '{ [key: string]: PropertyDefinition<keyof SupportedPropertyTypes, false>; }'.
Property 'foo' is incompatible with index signature.
Type '{ type: string; }' is not assignable to type 'PropertyDefinition<keyof SupportedPropertyTypes, false>'.
Types of property 'type' are incompatible.
Type 'string' is not assignable to type 'keyof SupportedPropertyTypes'.(2345)