Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs Typescript:通过添加具有特定命名的新字段来动态扩展接口_Reactjs_Typescript_Interface_React Context_Openapi Generator - Fatal编程技术网

Reactjs Typescript:通过添加具有特定命名的新字段来动态扩展接口

Reactjs Typescript:通过添加具有特定命名的新字段来动态扩展接口,reactjs,typescript,interface,react-context,openapi-generator,Reactjs,Typescript,Interface,React Context,Openapi Generator,我有这样一个界面: interface ProjectCostData { purchasePrice: number; propertyValue: number; recentlyDamaged: boolean; } 现在,我想基于上面的接口动态创建一个这样的接口: interface ProjectCostDataWithSetters { purchasePrice: number; setPurchasePrice: Dispatch<SetStateAc

我有这样一个界面:

interface ProjectCostData {
  purchasePrice: number;
  propertyValue: number;
  recentlyDamaged: boolean;
}
现在,我想基于上面的接口动态创建一个这样的接口:

interface ProjectCostDataWithSetters {
  purchasePrice: number;
  setPurchasePrice: Dispatch<SetStateAction<number>>;
  propertyValue: number;
  setPropertyValue: Dispatch<SetStateAction<number>>;
  recentlyDamaged: boolean;
  setRecentlyDamage: Dispatch<SetStateAction<boolean>>;
}
interface ProjectCostDataWithSetters{
采购价格:数量;
设置采购价格:发货;
propertyValue:数字;
setPropertyValue:分派;
最近损坏:布尔值;
setRecentlyDamage:调度;
}
-->映射到第一个接口上,并为每个条目A添加一个新条目B,其键为`set${entryKey}`和一个可以从条目A派生的类型

这在TS中可能吗


背景:我有一个基于OpenAPI的后端,它将API结构作为
.yaml
文件提供给我。我通过一个生成器传递该文件,并接收接口和函数以与API对话。在前端,我使用react上下文来构建一个全局状态。我想基于生成器的输出构建全局react上下文。

在typescript 4.0或更早版本中,这是不可能的。字符串,包括属性名,要么完全被称为常量(即
“foo”
),要么是一组有限的常量之一(即
“foo”|“bar”
),要么就是包含任何内容的任何字符串(
字符串
)。因此,不能基于其他属性名称构造新属性名称


然而,TypeScript4.1(目前为beta版)有一些功能可能在这方面有所帮助

有点怪


您甚至可以处理资本化更改:

interface Capitals { a: 'A', b: 'B', c: 'C' /* ... */, p: 'P' }

type Capitalize<T extends string> =
    T extends `${infer First}${infer Rest}`
        ? First extends keyof Capitals
            ? `${Capitals[First]}${Rest}`
            : T
        : T


type SetterName<T extends string> = `set${Capitalize<T>}`

type SetPropName = SetterName<'propName'> // type: "setPropName"
接口大写字母{a:'a',b:'b',c:'c'/*…*/,p:'p'}
类型资本化=
T扩展了`${inferfirst}${inferrest}`
? 首先是资本金
? `${大写[第一]}${Rest}`
:T
:T
类型SetterName=`set${Capitalize}`
键入SetPropName=SetterName//type:“SetPropName”


把所有这些放在一起会有点棘手,尤其是在测试版上。但我认为,从理论上讲,所有的片段都是为了完成这种类型转换而存在的。

在typescript 4.0或更高版本中,这是不可能的。字符串,包括属性名,要么完全被称为常量(即
“foo”
),要么是一组有限的常量之一(即
“foo”|“bar”
),要么就是包含任何内容的任何字符串(
字符串
)。因此,不能基于其他属性名称构造新属性名称


然而,TypeScript4.1(目前为beta版)有一些功能可能在这方面有所帮助

有点怪


您甚至可以处理资本化更改:

interface Capitals { a: 'A', b: 'B', c: 'C' /* ... */, p: 'P' }

type Capitalize<T extends string> =
    T extends `${infer First}${infer Rest}`
        ? First extends keyof Capitals
            ? `${Capitals[First]}${Rest}`
            : T
        : T


type SetterName<T extends string> = `set${Capitalize<T>}`

type SetPropName = SetterName<'propName'> // type: "setPropName"
接口大写字母{a:'a',b:'b',c:'c'/*…*/,p:'p'}
类型资本化=
T扩展了`${inferfirst}${inferrest}`
? 首先是资本金
? `${大写[第一]}${Rest}`
:T
:T
类型SetterName=`set${Capitalize}`
键入SetPropName=SetterName//type:“SetPropName”


把所有这些放在一起会有点棘手,尤其是在测试版上。但我认为,从理论上讲,所有的部分都是为了完成这种类型转换而存在的。

这个生成器是否也能为您制作这些设置界面?我不知道:/它是typescript与fetch相结合的生成器,我需要的是非常具体的。生成的代码对于我的用例来说太通用了。我明白了。如果实现setter的逻辑足够通用,您可以在接口的
keyof
上的单个函数中实现它们,比如
function setProp(obj:I,prop:K):Dispatch{/*使用`obj[prop]:I[K]`here*/}
这个生成器也不能为您制作这些设置界面吗?我不知道:/它是typescript与fetch结合使用的生成器,我需要的是非常特定的。生成的代码对于我的用例来说太通用了。我明白了。如果实现setter的逻辑足够通用,您可以在接口的
keyof
上的单个函数中实现它们,比如
function setProp(obj:I,prop:K):Dispatch{/*使用`obj[prop]:I[K]`here*/}
interface Capitals { a: 'A', b: 'B', c: 'C' /* ... */, p: 'P' }

type Capitalize<T extends string> =
    T extends `${infer First}${infer Rest}`
        ? First extends keyof Capitals
            ? `${Capitals[First]}${Rest}`
            : T
        : T


type SetterName<T extends string> = `set${Capitalize<T>}`

type SetPropName = SetterName<'propName'> // type: "setPropName"