简体   繁体   English

具有已知属性的 Typescript 对象

[英]Typescript object with a known property

Help to define generic, which accepts Object with type T and K property key in T and returns typed T .帮助定义泛型,它接受Object with type T K property key in T并返回类型化的T

My attempts to figure out how it can be solved with TypeScript 4:我试图弄清楚如何使用 TypeScript 4 解决它:

  1. It solves the problem, but returns object .它解决了问题,但返回object It's not good solution.这不是很好的解决方案。
type WithProp<TKey extends string> = { [K in TKey]: object };

Playground . 游乐场

  1. The same, but returns any .相同,但返回any It is better to write something like T[K] , but TS said that TS2536: Type 'K' cannot be used to index type 'T' .最好写一些类似T[K]东西,但 TS 说TS2536: Type 'K' cannot be used to index type 'T'
type WithProp<T, K extends string | number> = T & {[keyToSort in K]: any};

Playground . 游乐场


Usage:用法:

const prop = <K extends string | number>(prop: K) => <T>(model: WithProp<T, K>) => model[prop];
const x = {foo: 'bar', baz: 'qux'};

typeof prop('foo')(x) === typeof x.foo;

And calling the helper with any key (except of 'foo' or 'baz' ) on x must throw an error.并且在x上使用任何键( 'foo''baz'除外)调用 helper 必须抛出错误。

Please, help to write a helper.请帮忙写一个助手。

If I'm understanding the question, then a conditional which checks that T contains a property K is what you want.如果我理解这个问题,那么检查T包含属性K条件就是你想要的。 Try:尝试:

type WithProp<T, K extends string|number> = T extends { [k in K]: any } ? T : never

Then used with your code:然后与您的代码一起使用:

function prop<K extends string | number>(prop: K) {
    return function<T> (model: WithProp<T, K>) { 
        return model[prop];
    }
}

const x = { foo: 'bar', baz: 'qux' };

typeof prop('foo')(x) === typeof x.foo; // Works

prop('blah')(x); // Error, argument is not assignable to never

Not the most descriptive error message, but it gets the job done.不是最具描述性的错误消息,但它完成了工作。

For a better error message, we can re-write things slightly and instead of WithProp we can just put the constraint in the template argument list.为了更好的错误信息,我们可以稍微重写一些东西,而不是WithProp我们可以将约束放在模板参数列表中。

function prop<K extends string | number>(prop: K) {
    return function<T extends { [k in K]: any }> (model: T) { 
        return model[prop];
    }
}

Now we'll get:现在我们将得到:

prop('blah')(x) // Error, Property 'blah' is missing in type '{ foo: string; baz: string; }' but required in type '{ blah: any; }'

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

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