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<...>) 
*/