简体   繁体   English

如何避免在 Typescript 中的每次使用时重复泛型类型约束?

[英]How to avoid repeating generic type constraints with every usage in Typescript?

How do you avoid repeating types constantly when using generics in Typescript?在 Typescript 中使用 generics 时如何避免不断重复类型? If I have some constraint on a generic type then I must repeat that constraint anywhere I use the generic type.如果我对泛型类型有一些约束,那么我必须在使用泛型类型的任何地方重复该约束。 This is tedious and not very DRY.这很乏味而且不是很干。

//A constraint on this generic
type MyConstraint = { bar: number }
type GenericOne<T extends MyConstraint> = {
    foo: T
}

To create an instance I annoyingly have to repeat the constraint because TS only does generic inference on functions要创建一个实例,我不得不重复约束,因为 TS 只对函数进行通用推理

//This annoyance would I think be solved by generic values https://github.com/microsoft/TypeScript/issues/17574
const testok: GenericOne<MyConstraint> = { foo: { bar: 1 } }

Now if I want to use my generic type in other places I also have to repeat the constraint!现在,如果我想在其他地方使用我的泛型类型,我还必须重复约束!

const makeGenericOne2: <T extends MyConstraint>(arg: GenericOne<T>) => GenericOne<T> = (arg) => {
    return arg
}

At least now I can create from object literals without repeating myself至少现在我可以从 object 文字创建而无需重复自己

const test5 = makeGenericOne2({ foo: { bar: 1 } })
// And I get nice error messsages
const test6 = makeGenericOne2({foo: {baz: 1}})

The only way to avoid repeating the constraint seems to be a conditional type with inference避免重复约束的唯一方法似乎是带有推理的条件类型

const makeGenericOne: <T>(arg: T extends GenericOne<infer U> ? T : never) => T = (arg) => {
    return arg
}

I can still create instances from object literal without repeating myself我仍然可以从 object 文字创建实例,而无需重复自己

const test3 = makeGenericOne({ foo: { bar: 1 } })

But now the error messages aren't so nice.但是现在错误消息不是那么好。

//"number not assignable to never" instead of { baz: 1 } is missing property "bar: number"
const test4 = makeGenericOne({ foo: { baz: 1 } })

It seems like the following is needed -- infer T because we know it must extend Myconstraint似乎需要以下内容——推断 T 因为我们知道它必须扩展 Myconstraint

const propagateGeneric: <infer T>(arg: GenericOne<T>) => GenericOne<T>

Unfortunately this isn't allowed in TS at the moment.不幸的是,目前 TS 不允许这样做。

How do I "propogate" the constraint on a generic type to avoid repeating it everywhere that generic type is used?如何在泛型类型上“传播”约束以避免在使用泛型类型的任何地方重复它?

Sandbox Link 沙盒链接

Tricky but it seems to work棘手,但它似乎工作

//A constraint on this generic
type MyConstraint = { bar: number }
type GenericOne<T extends MyConstraint = MyConstraint> = {
    foo: T
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM