Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.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
Typescript 使用K扩展T的键时T[K]的变窄类型_Typescript_Generics - Fatal编程技术网

Typescript 使用K扩展T的键时T[K]的变窄类型

Typescript 使用K扩展T的键时T[K]的变窄类型,typescript,generics,Typescript,Generics,我试图定义一个接口,其中: 一个属性是泛型类型的键 另一个属性依赖于另一个属性中与该键关联的值的类型 我能得到的最接近的结果是Typescript将T[K]解析为T的所有值的联合类型。但是,如果K是已知的字符串文字,似乎应该有某种方法进一步缩小这个范围 这是一个我正在尝试做的例子 试验 接口人{ 年龄:人数; 名称:字符串; } 接口列定义{ 关键词:K; renderData:(值:T[K])=>void; } 接口报告{ 列:ColumnDef[]; } 常数报告:报告={ 栏目:[ {

我试图定义一个接口,其中:

  • 一个属性是泛型类型的键
  • 另一个属性依赖于另一个属性中与该键关联的值的类型
我能得到的最接近的结果是Typescript将T[K]解析为T的所有值的联合类型。但是,如果K是已知的字符串文字,似乎应该有某种方法进一步缩小这个范围

这是一个我正在尝试做的例子

试验

接口人{
年龄:人数;
名称:字符串;
}
接口列定义{
关键词:K;
renderData:(值:T[K])=>void;
}
接口报告{
列:ColumnDef[];
}
常数报告:报告={
栏目:[
{
key:“age”//这是正确键入的“age”|“name”
renderData:(值)=>{
//理想情况下,这里的值应该是“number”,但它是“string | number”
}
},
{
key:“name”//这是正确键入的“age”|“name”
renderData:(值)=>{
//理想情况下,这里的值应该是“string”,但它是“string | number”
}
},
]
}

根据yossarian上尉提出的相关问题,我可以使用

为了进一步帮助某人,下面是我如何将其应用到我的示例中

interface Person {
    age: number;
    name: string;
}

type ColumnDef<T> = {
    [K in keyof T]-?: BaseColumnDef<T, K>
  }[keyof T]


interface BaseColumnDef<T, K extends keyof T> {
    key: K;
    renderData: (value: T[K]) => void;
}

interface Report<T> {
    columns: ColumnDef<T>[];
}

const report: Report<Person> = {
    columns: [
        {
            key: "age", // this is correctly typed to be "age"|"name"
            renderData: (value) => {
                // value is now type "number"
            }
        },
        {
            key: "name", // this is correctly typed to be "age"|"name"
            renderData: (value) => {
                // value is now type "string"
            }
        },
    ]
}
接口人{
年龄:人数;
名称:字符串;
}
类型ColumnDef={
[K in keyof T]-?:BaseColumnDef
}[keyof T]
接口BaseColumnDef{
关键词:K;
renderData:(值:T[K])=>void;
}
接口报告{
列:ColumnDef[];
}
常数报告:报告={
栏目:[
{
key:“age”//这是正确键入的“age”|“name”
renderData:(值)=>{
//值现在是“number”类型
}
},
{
key:“name”//这是正确键入的“age”|“name”
renderData:(值)=>{
//值现在是“字符串”类型
}
},
]
}

我坚信这个答案会对您有所帮助。我甚至想说,你的问题是可疑的,这似乎是相关的。我会仔细考虑这个问题,看看我是否能把它应用到我的情况中。你说得对,这正是我所需要的。谢谢你给我指明了正确的方向。
interface Person {
    age: number;
    name: string;
}

type ColumnDef<T> = {
    [K in keyof T]-?: BaseColumnDef<T, K>
  }[keyof T]


interface BaseColumnDef<T, K extends keyof T> {
    key: K;
    renderData: (value: T[K]) => void;
}

interface Report<T> {
    columns: ColumnDef<T>[];
}

const report: Report<Person> = {
    columns: [
        {
            key: "age", // this is correctly typed to be "age"|"name"
            renderData: (value) => {
                // value is now type "number"
            }
        },
        {
            key: "name", // this is correctly typed to be "age"|"name"
            renderData: (value) => {
                // value is now type "string"
            }
        },
    ]
}