所以我试图根据传入的参数来获取对象。
我发现了这个问题,它与我之后的问题非常接近。
TypeScript function return type based on input parameter
但是,我希望该函数也能够接受字符串,并且当传入的参数不是文字类型时,它将推断any or unknown
让我在代码中表达我的意思。
interface Circle {
type: "circle";
radius: number;
}
interface Square {
type: "square";
length: number;
}
type TypeName = "circle" | "square" | string;
type ObjectType<T> =
T extends "circle" ? Circle :
T extends "square" ? Square :
unknown;
function getItems<T extends TypeName>(type: T) : ObjectType<T>[] {
...
}
请注意,TypeName
具有文字类型和字符串的并集类型。
我希望看到的是,当我使用类型时,我能够根据参数推断出返回类型。例如:
const circle = getItems('circle'); // infers: Circle
const something = getItems('unknown'); // infers: unknown
以上都很好。但是,我无法让IDE建议这些选项。
我希望看到以下选项:'circle' | 'square' | string
。
那有可能吗?
答案 0 :(得分:0)
不,这是不可能的,因为string
是字符串文字的超级类型,所以
type TypeName = "circle" | "square" | string;
与
没什么不同type TypeName = string;
但是,您可以使用函数重载来实现目标
type TypeName = "circle" | "square"
type ObjectType<T> =
T extends "circle" ? Circle :
T extends "square" ? Square :
never
function getItems<T extends TypeName>(type: T) : ObjectType<T>[]
function getItems(type: string) : unknown[]
function getItems(type: string) {
// implementation comes here
}
答案 1 :(得分:0)
您可以使用重载和一些条件实用程序类型来做到这一点:
interface Circle {
type: "circle";
radius: number;
}
interface Square {
type: "square";
length: number;
}
type KnownObject = Circle | Square
type IsKnownTypeName<T extends string, U = KnownObject> = U extends { type: T } ? T : never
type ObjectForType<T extends string, U = KnownObject> = U extends { type: T } ? U : never
function getItems<T extends string>(type: IsKnownTypeName<T>) : ObjectForType<T>[]
function getItems<T extends string>(type: T) : any[]
function getItems<T extends string>(type: T) : any[] {
return []
}
const circle = getItems('circle'); // infers: Circle
const something = getItems('unknown'); // infers: any