我正在尝试使用通用打字和打字稿界面来描述以下情况。 当函数将工厂创建的对象的属性从[keys] .option.value。(number | string ...)转换为选项。[Keys]。(number | string ...)
在最后一行我使用intValue而不是数字。对于Values类型有什么魔力吗?
interface Validator { }
interface Value<T> {
value: T
validator: Validator
}
interface intValue extends Value<number> {}
interface stringValue extends Value<string> {}
interface Entity {
(key: string): intValue | stringValue
}
interface Dog extends Entity {
id: intValue;
age: intValue;
name: stringValue;
}
function initObject<E extends Entity>(arg: E): E {
return arg;
}
function initInt(value: number, validator: Validator): intValue {
return {
value: value,
validator: validator
}
}
function initString(value: string, validator: Validator): stringValue {
return {
value: value,
validator: validator
}
}
type Values<T> = {
[P in keyof T]?: T[P];
}
interface Valued<V> {
values: Values<V>;
validators: Values<V>;
}
function getValued<V extends Entity>(obj: V): Valued<V>{
let out: Valued < V > = {values:[]};
for (let key in obj) {
const o:intValue = obj[key];
out.values[key] = o.value;
out.validators[key] = o.validator;
}
return out;
}
const objectDog = initObject(<Dog>{
id: initInt(1, {}),
age: initInt(12, {}),
name: initString("Nuf", {})
})
const valuedDog = getValued(objectDog);
valuedDog.values.id; // There id is type intValue i want get number type here
谢谢,求助。
答案 0 :(得分:1)
我无法花时间浏览所有代码,但看起来就像您希望str1[3] * hex_np + str2[5]
的定义如下:
Values<>
也就是说,type Values<V extends Entity> = {
[P in keyof V]?: V[P]['value'];
}
类型应该“展开”Values<V>
中的属性值。然后,您只需将V
更改为Valued<V>
:
Valued<V extends Entity>
然后你的代码类型检查并返回或多或少的你想要的东西(好吧,它是interface Valued<V extends Entity> {
values: Values<V>;
validators: Values<V>;
}
,因为number | undefined
属性是可选的...如果你删除Values<>
不要那样)。不确定代码是否符合您的要求,但您可能是最好的判断。
希望有所帮助;祝你好运!
答案 1 :(得分:0)
我按照您的描述获得了以下代码。我认为这些变化是可以接受的。如果没有,请说明原因,我会再看看。
interface Validator { }
interface Value<T> {
value: T
validator: Validator
}
interface intValue extends Value<number> {}
interface stringValue extends Value<string> {}
interface Entity {
(key: string): intValue | stringValue
}
interface Dog extends Entity {
id: intValue;
age: intValue;
name: stringValue;
}
function initObject<E extends Entity>(arg: E): E {
return arg;
}
function initInt(value: number, validator: Validator): intValue {
return {
value: value,
validator: validator
}
}
function initString(value: string, validator: Validator): stringValue {
return {
value: value,
validator: validator
}
}
type Values<T> = {
[P in keyof T]?: T[P];
}
interface Valued<V> {
values: Values<V>;
validators: Values<V>;
}
function getValued<V extends Entity>(obj: V): Valued<V>{
// initialize to empty object not array and initialize validators
let out: Valued<V> = { values: {}, validators: {} };
// const instead of let
for (const key in obj) {
const o:intValue = obj[key];
out.values[key] = o.value;
out.validators[key] = o.validator;
}
return out;
}
const objectDog = initObject(<Dog>{
id: initInt(1, {}),
age: initInt(12, {}),
name: initString("Nuf", {})
}); // semicolon
const valuedDog = getValued(objectDog);
// Added .value here
valuedDog.values.id.value;
P.S。我希望这种抽象风格有一个真正的充分理由。