Typescript中具有严格形状约束的泛型类型

Typescript中具有严格形状约束的泛型类型,typescript,Typescript,查看以下代码时: type Test<T extends {a: number}> = ...doing something with keyof T... Test<{a:1}> // ok Test<{a:1, b:1}> // ok, but I want this to fail due to having 'b'; type Test=…使用keyof T做某事。。。 测试//正常 测试//好,但我希望由于有“b”而失败; 通过严格限制形状和不

查看以下代码时:

type Test<T extends {a: number}> = ...doing something with keyof T...

Test<{a:1}> // ok
Test<{a:1, b:1}> // ok, but I want this to fail due to having 'b';
type Test=…使用keyof T做某事。。。
测试//正常
测试//好,但我希望由于有“b”而失败;

通过严格限制形状和不允许额外属性,有没有办法使第一个可以,但第二个不可以。

您不能直接使用它,但您可以通过使用条件类型来确保如果该类型具有额外属性,则该类型将不会真正可用:

type Test<T extends { a: number }> = Exclude<keyof T, keyof { a: number }> extends never ?  T : "T must be exactly of type { a: number }";
let ok: Test<{ a: number }> = { a: 10 }; // ok
let nok: Test<{ a: number, b: number }> = { a: 1, b: 2 }// nok; Type '{ a: number; b: number; }' is not assignable to type '"T must be exactly of type { a: number }"'.
但如果类型兼容(即具有更多属性),则允许从其他源分配

上述类型(或其变体)可以帮助我们创建一个函数,在该函数中,我们不需要过多的属性,并且可以推断出泛型参数:

function create<T extends { a: number }>(p: T & (Exclude<keyof T, keyof { a: number }> extends never ?  T : "T must be exactly of type { a: number }")) : T{

}
create({ a: 1, b: 1 }); //Type '{ a: number; b: number; }' is not assignable to type '"T must be exactly of type { a: number }"'.
create({ a: 1 }); //ok
functioncreate(p:T&(Exclude-extensed-never?T:“T必须是{a:number}类型”):T{
}
创建({a:1,b:1})//类型“{a:number;b:number;}”不能赋值给类型“'T必须完全是类型{a:number}”。
创建({a:1})//好啊
但第二个是不确定的,严格限制形状,不允许额外的属性


不是泛型。用它的值替换每个T,例如用
类型测试={a:number}
替换
类型测试={a:number}

测试
是一件奇怪的事情,它指定的是数字文本类型,而不是值。如果希望
Test
s仅包括
a
,则希望
type Test={a:number},当然?然后
const t:Test={a:1,b:1}将是一个错误。您似乎混淆了泛型类型和值。这不是真的。您不知道在“…”中正在进行什么测试。它可以用T的
keyof做非常复杂的事情,它与
type Test={a:number}不同
{a:1}
没有问题。它正确地扩展了
{a:number}
。当你创建一些东西的hashmap时,它可能是有用的类型。谢谢!这就是我一直在寻找的答案@Joon添加了更多的讨论,不确定
Test
本身有多有用,但该技术适用于推断
T
的函数。非常感谢!你一直以来都在帮我回答我的每一个问题。我需要限制并且不允许泛型类型别名有过多的属性,我一直有问题,但现在问题解决了?T:“T必须是{a:number}类型”
您可以选择更简单的
{[K in Exclude]:never}
let ab = { a: 1, b: 1 };
let a: { a: number } = ab // ok
function create<T extends { a: number }>(p: T & (Exclude<keyof T, keyof { a: number }> extends never ?  T : "T must be exactly of type { a: number }")) : T{

}
create({ a: 1, b: 1 }); //Type '{ a: number; b: number; }' is not assignable to type '"T must be exactly of type { a: number }"'.
create({ a: 1 }); //ok