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[]; } 常数报告:报告={ 栏目:[ {
- 一个属性是泛型类型的键
- 另一个属性依赖于另一个属性中与该键关联的值的类型
接口人{
年龄:人数;
名称:字符串;
}
接口列定义{
关键词: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"
}
},
]
}