我从api(int main()
{
int width = 512;
int height = 512;
std::ofstream ofs("plot.ppm", std::ios::out);
ofs << "P3\n" << width << " " << height << "\n255\n";
for (int h = 0;h< height;h++) {
for (int w = 0; w < width; w++) {
vec3f col;
float x = ((float)w - 256);
float y = -((float)h - 256);
if (h == 256||w==256)col = vec3f(0, 0, 0);//axes
else col = vec3f(1,1,1);//background
if (y==x)col = vec3f(0, 0, 0);//straight line
if ((y*y) == (4*16*x))col=vec3f(1, 0, 0);//parabola
int r = int(255.99 * col.x);
int g = int(255.99 * col.y);
int b = int(255.99 * col.z);
ofs << r << " " << g << " " << b << "\n";
}
}
ofs.close();
}
)获得带有用户详细信息的json。该api还提供了响应的类型(plot.ppm
,当api更新其响应结构时,该接口会自动导入我的代码库中。
我从api中读取了json并添加了其他有用的属性,从而创建了readUserFromApi
。创建interface User
时,我只想提供 api没有提供的属性。将来,如果api还将为用户提供detailedUser
,则我代码中的detailedUser
将自动更新,并且我想输入一个打字错误,告诉我不需要手动提供{{ 1}}在构建name
时,因为interface User
已经来自api。
我有一个解决方案,请参见name
,但应该有一个更优雅的解决方案...
(code)
detailedUser
答案 0 :(得分:0)
对于DetailedUser
类型,如果我们使用类型别名而不是接口,则可以直接在类型中得到错误。对于这种简单类型,例如对象类型,应该没有实际的区别。
interface User {
id: number
//name: string // comment this and you get an error below
}
type SafeExtend<TBase, TExt extends Record<Extract<keyof TBase, keyof TExt>, never>> = TBase & TExt
type DetailedUser = SafeExtend<User, {
name: string
sex: string
}>
SafeExtend
将采用基本界面(User
),其类型包含要添加的任何其他字段。如果添加的字段已经在基本界面中,则会出现错误。
对于第二部分,如果您指定字段,则希望在扩展中出现错误,我认为使用扩展是不可能的。如果您改用函数,则可以这样做:
function safeSpread<TBase, TExt>(base: TBase, ext: TExt & Record<Extract<keyof TBase, keyof TExt>, never> ) {
return {
...base,
...ext
};
}
const detailedUser: DetailedUser = safeSpread(user, {
name: 'default name',
sex: 'f',
id: 0 // error
})