[我想]
interface T {
a?: string;
b?: number;
c?: boolean;
d?: object;
e?: null;
}
type A = {
a: string;
b: number;
q: string; // not exist in type T
}
type B = {
a: string;
b: number;
}
type G<U extends T> = {
data: U;
creator: () => void;
}
const someFunc = <U>(data: U): G<U> => {
return {
data,
creator: () => { console.log(data ) }
}
}
const funcA = (data: A) => {
const something = someFunc<A>(data); // I want to occur error
}
const funcB = (data: B) => {
const something = someFunc<B>(data); // I want to do well
}
类型'T'具有可选属性(每个属性)。
一种类型是类型“ T”(是“ B”)的子集
另一个不是“ T”类型的子集(是“ A”-具有属性“ q”)
但是,使用“ B”类型不会发生错误。
怎么办?
谢谢。
答案 0 :(得分:2)
没有错误的原因是我们所说的"msg": "error running gluster (/usr/sbin/gluster --mode=script volume add-brick var-www replica 2 server01-private:/server01-private:/data/glusterfs/var-www/brick01/brick server01-private:/server02-private:/data/glusterfs/var-www/brick02/brick server02-private:/server01-private:/data/glusterfs/var-www/brick01/brick server02-private:/server02-private:/data/glusterfs/var-www/brick02/brick force) command (rc=1): internet address 'server01-private:/server01-private' does not conform to standards\ninternet address 'server01-private:/server02-private' does not conform to standards\ninternet address 'server02-private:/server01-private' does not conform to standards\ninternet address 'server02-private:/server02-private' does not conform to standards\nvolume add-brick: failed: Host server01-private:/server01-private is not in 'Peer in Cluster' state\n"
的意思,这意味着-“我接受所有具有T的所有属性的U”。我们的T是非常松散的类型,每个属性都是可选的,然后只包含这些属性的一部分的类型完全可以,因为原始T从未说过字段是强制性的。让我们进行类型级别检查以证明我的话:
U extends T
您可以问-为什么A是否有其他字段。是的,它具有但也满足T的所有要求,这个附加字段不会破坏T的所有属性都在A中的事实。同样从实际的思维方式来看,如果我们使用属性让我们说a和b,那么如果对象具有q,这不是问题,因为我们不使用此属性,所以不会发生任何不良情况。
仅供参考。在键迭代之外,禁止附加属性没有实际的意义。但是,如果您对此感兴趣,这里是完整的解决方案-Advanced TypeScript Exercises - Answer 7
答案 1 :(得分:2)
如果对象存储在变量中,FYI Typescript允许过多的属性:
解决这些检查的最后一种方法,可能有点 令人惊讶的是将对象分配给另一个变量: squareOptions不会进行过多的属性检查,编译器不会 给你一个错误。 https://www.typescriptlang.org/docs/handbook/interfaces.html#excess-property-checks
因此,即使您的函数期望使用T
,它也会起作用:
interface T {
a?: string;
b?: number;
c?: boolean;
d?: object;
e?: null;
}
interface A {
a: string;
b: number;
q: string; // not exist in type T
}
const foo: A = {
a: "a",
b: 1,
q: "q",
};
const someFunc = (data: T) => console.log(data);
someFunc(foo);
在您的示例中,它“更有效”,因为您期望扩展T
(在此行type G<U extends T> = {
中),这意味着任何尊重接口T
的事物而A
确实如此。
其他说明:您的函数someFunc
对类型U没有限制,因此它将接受任何内容:
const funcC = (data: number) => {
const something = someFunc<number>(data); // Also valid
}
要最终回答您的问题并能够禁止使用其他属性,请在此处提供详细的答案:https://stackoverflow.com/a/57117594/3292234