繁体   English   中英

打字稿如何推断文字类型或字符串

[英]Typescript how to infer Literal types or string

所以我试图根据传入的参数获取一个对象。我发现了这个问题,它非常接近我所追求的。 TypeScript 函数根据输入参数返回类型但是,我希望该函数也能够接受字符串,并且当传入的参数不是文字类型时,它会推断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 'circle' | 'square' | string 'circle' | 'square' | string

那有可能吗?

不,这是不可能的,因为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
}

无论如何,这是一个新的黑客

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>[]  {
    ...
}

自己试试

您可以使用重载和一些条件实用程序类型来做到这一点:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM