Typescript 如果泛型扩展接口,则需要所有参数
我有一组接口和一个通用接口。 这个通用接口可能扩展接口集中的任何接口,但如果扩展了,我希望它需要扩展接口中的所有值Typescript 如果泛型扩展接口,则需要所有参数,typescript,Typescript,我有一组接口和一个通用接口。 这个通用接口可能扩展接口集中的任何接口,但如果扩展了,我希望它需要扩展接口中的所有值 接口一{ b:布尔型, c:号码 } 接口二{ d:字符串[] f:布尔[] } 函数F(p:K)=>。。。。。 事实上,我想要的是 K扩展一个和两个 但这应该是一个错误: const a = {b: true, c:2, d:["as"]} F(a) 我正在重命名您的类型,使其更为传统: interface One { b: boolean; c: number; }
接口一{
b:布尔型,
c:号码
}
接口二{
d:字符串[]
f:布尔[]
}
函数F(p:K)=>。。。。。
事实上,我想要的是
K扩展一个和两个
但这应该是一个错误:
const a = {b: true, c:2, d:["as"]}
F(a)
我正在重命名您的类型,使其更为传统:
interface One {
b: boolean;
c: number;
}
interface Two {
d: string[];
f: boolean[];
}
这里的一个问题是TypeScript中的类型是可扩展的,而不是。因此值{b:true,c:2,d:[“as”]}
是One | Two
的一个完全有效的实例,因为它可以赋值给One
。通常,您会得到关于d
的警告,但由于d
是Two
的一部分,编译器不会将其视为多余属性
一个想法是使用a来表示“不具有T的任何属性的东西”,如下所示:
type NoneOf<T> = { [K in keyof T]?: never };
你可以看到它的工作原理:
const a: DesiredType = {b: true, c:2, d:["as"]}; // error
const okay: DesiredType = {b: true, c: 2}; // okay
但是你说你想要N个接口,比如说
interface Three {
g: number[];
h: string;
}
我想,你需要一些程序化的东西,可以把(One | Two | Three | Four | |···············································。这是可能的,请使用以下变体:
这些都被接受,但以下内容被拒绝:
f({ b: true, c: 1, d: [""] }); // error!
/*
Argument of type '{ b: true; c: number; d: string[]; }'
is not assignable to parameter of type '(One & Two & Three) |
(One & Two & NoneOf<Three>) | (One & NoneOf<Two> & Three) |
(One & NoneOf<Two> & NoneOf<Three>) | (NoneOf<One> & Two & Three) |
(NoneOf<One> & Two & NoneOf<...>) |
(NoneOf<...> & ... 1 more ... & Three) |
(NoneOf<...> & ... 1 more ... & NoneOf<...>)
*/
f({b:true,c:1,d:[“”]});//错误!
/*
类型为“{b:true;c:number;d:string[];}”的参数
不可分配给类型为“(一、二、三)的参数
(一、二、三)
(一、二、三)
(不属于&两个&不属于)|
(不包括&…1个…&3个)|
(不属于&…1个以上……&不属于)
*/
这个错误消息可能有点神秘,因为它基本上是N次幂2的交集的并集,但希望它足够好
好吧,希望这会有帮助;祝你好运
您的游乐场示例与此处的代码不同。它在two
中不包含f
。您到底有什么问题<代码>函数F(p:K)
对我来说很好。更新了链接。我想要一个错误,因为接口2没有完全实现,const a={b:true,c:2}
不应该是一个错误,因为其中一个是完全实现的,所以您希望它采用接口1或接口2,或者两者都采用?但不是介于两者之间的东西?确切地说,接口集可以是N,所以。。。一、二、三等等……非常感谢你的帮助!我真的很感激。你能再解释一下为什么这项工作吗?你知道它是如何工作的吗<代码>A | B
表示A
或B
(这是一个包含的“或”),因为既是A
又是B
的东西是有效的A
),而A&B
表示A
和B
。由于类型不精确,One&Two
意味着它具有来自One
的属性和来自Two
的属性。因此,可分配给(One | NoneOf)和(Two | NoneOf)
的属性必须是One
或NoneOf
,并且它也必须是Two
或NoneOf
。这就是你想要描述的类型。。。它具有One
的全部或全部属性,以及Two
的全部或全部属性。这对你有意义吗?
type UnionToAllOrNone<U> = (U extends any
? (k: U | NoneOf<U>) => void
: never) extends ((k: infer I) => void)
? I
: never;
type I = UnionToAllOrNone<One | Two | Three>;
function f(i: I) {}
f({}); // none of them
f({ b: true, c: 1 }); // just One
f({ d: [""], f: [true] }); // just Two
f({ g: [1], h: "" }); // just Three
f({ b: true, c: 1, d: [""], f: [true] }); // One and Two
f({ b: true, c: 1, d: [""], f: [true], g: [1], h: "" }); // One, Two, Three
f({ b: true, c: 1, d: [""] }); // error!
/*
Argument of type '{ b: true; c: number; d: string[]; }'
is not assignable to parameter of type '(One & Two & Three) |
(One & Two & NoneOf<Three>) | (One & NoneOf<Two> & Three) |
(One & NoneOf<Two> & NoneOf<Three>) | (NoneOf<One> & Two & Three) |
(NoneOf<One> & Two & NoneOf<...>) |
(NoneOf<...> & ... 1 more ... & Three) |
(NoneOf<...> & ... 1 more ... & NoneOf<...>)
*/