如何解决Typescript 类型推断和可选的对象属性
基本上我想要实现的是让类 X 从提供的构造函数参数类型推断其 K 类型。
我写了这个:
interface XContstructorParams<K extends string = never> {
record?: Record<K,number>;
// Other stuff with some being optionals,which is why it's all in single
// object,as I don't want to do new X(arg1,undefined,arg2)
}
class X<K extends string = never> {
private record: Record<K,number>;
constructor(params: XContstructorParams<K>) {
// I'd rather avoid to use a type assertion here but it's not a big deal
// compared to the issue below.
this.record = params.record || {} as Record<K,number>;
}
getNumber(k: K): number {
return this.record[k];
}
}
这实际上可以在未提供 record
属性时推断 K 的类型为 never,但它不会阻止手动为 K 指定不正确的值:
// Correctly inferred to be X<'a','b'>
const x1 = new X({ record: {'a': 1,'b': 2} });
// Correctly inferred to be X<never>
const x2 = new X({});
// Oops ! This is incorrect as `getNumber` will not return a number when called with 'c'
// or 'd ! But it is allowed because of how I wrote the constructor `record` property to
// be optional. I want it to be optional only when K is never. It's either you provided
// a record and it's keys determine K,or you didn't give a record and K is never,but
// should not be able to specify K and not provide a record matching your specified K.
const x3 = new X<'c' | 'd'>({});
我希望将 x3 识别为编译错误,但我无法使其正常工作。我做错了什么?
编辑:出于某种原因,堆栈溢出在消息的开头删除了我的“你好”,所以......我猜迟到总比没有好......你好,感谢您的帮助! ;-)
解决方法
此解决方案适合您吗?
interface XContstructorParams<K extends string = never> {
record: K extends never ? undefined : Record<K,number>;
// Other stuff with some being optionals,which is why it's all in single
// object,as I don't want to do new X(arg1,undefined,arg2)
}
class X<K extends string = never> {
private record: Record<K,number>;
constructor(params: XContstructorParams<K>) {
// I don't think you need type castin here
this.record = params.record
}
getNumber(k: K): number {
return this.record[k];
}
}
// Correctly inferred to be X<'a','b'>
const x1 = new X({ record: { 'a': 1,'b': 2 } });
const result = x1.getNumber('a') // number
const x2 = new X<never>({}); // error
const x3 = new X<'c' | 'd'>({}); // error
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。