是否有方法更改*.d中定义的接口属性的类型?Ts在typescript中?
例如:
x.d.ts中的接口定义为
interface A {
property: number;
}
我想在我写入的typescript文件中改变它
interface A {
property: Object;
}
甚至这个也可以
interface B extends A {
property: Object;
}
这种方法有效吗?当我试我的系统时,它不工作。只是想确认一下有没有可能?
不能更改现有属性的类型。
你可以添加一个属性:
interface A {
newProperty: any;
}
而是改变现有的一种类型:
interface A {
property: any;
}
导致一个错误:
后续变量声明必须具有相同的类型。变量
'property'必须是'number'类型,但这里有'any'类型
当然,您可以拥有自己的接口来扩展现有的接口。在这种情况下,你可以重写一个类型到一个兼容的类型,例如:
interface A {
x: string | number;
}
interface B extends A {
x: number;
}
顺便说一下,你可能应该避免使用Object作为类型,而是使用any类型。
在任何类型的文档中,它声明:
any类型是使用现有JavaScript的强大方式,
允许您在过程中逐渐选择加入或退出类型检查
编译。您可能希望Object扮演类似的角色
在其他语言中是这样。但是Object类型的变量只允许你
要给它们赋值-你不能调用任意的方法
他们,甚至那些真实存在的人:
let notSure: any = 4;
notSure.ifItExists(); // okay, ifItExists might exist at runtime
notSure.toFixed(); // okay, toFixed exists (but the compiler doesn't check)
let prettySure: Object = 4;
prettySure.toFixed(); // Error: Property 'toFixed' doesn't exist on type 'Object'.
稍微扩展一下@zSkycat的回答,您可以创建一个泛型,它接受两种对象类型,并返回一个合并的类型,其中第二个对象类型的成员覆盖第一个对象类型的成员。
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
type Merge<M, N> = Omit<M, Extract<keyof M, keyof N>> & N;
interface A {
name: string;
color?: string;
}
// redefine name to be string | number
type B = Merge<A, {
name: string | number;
favorite?: boolean;
}>;
let one: A = {
name: 'asdf',
color: 'blue'
};
// A can become B because the types are all compatible
let two: B = one;
let three: B = {
name: 1
};
three.name = 'Bee';
three.favorite = true;
three.color = 'green';
// B cannot become A because the type of name (string | number) isn't compatible
// with A even though the value is a string
// Error: Type {...} is not assignable to type A
let four: A = three;
我已经创建了这个类型,允许我轻松地覆盖嵌套接口:
export type DeepPartialAny<T> = {
[P in keyof T]?: T[P] extends Obj ? DeepPartialAny<T[P]> : any;
};
export type Override<A extends Obj, AOverride extends DeepPartialAny<A>> = { [K in keyof A]:
AOverride[K] extends never
? A[K]
: AOverride[K] extends Obj
? Override<A[K], AOverride[K]>
: AOverride[K]
};
然后你可以这样使用它:
interface Foo {
Bar: {
Baz: string;
};
}
type Foo2 = Override<Foo, { Bar: { Baz: number } }>;
const bar: Foo2['Bar']['Baz'] = 1; // number;
基于ZSkycat的出色回答,您可以创建一个抽象的Override泛型类型,该类型易于使用并清楚地解释了代码的意图。
type Override<T, K extends keyof T, N> =省略<T, K> & {[K中的K1]: N};
地点:
现有类型
K =您希望覆盖的类型的键
N =要覆盖现有类型的键的新类型
使用示例:
type GraphQLCodegenConfig =覆盖<CodegenConfig, 'schema', DocumentNode>;
更好的解决方案是使用以下修改类型(双关语)的这个答案
export type Modify<T, R extends Partial<T>> = Omit<T, keyof R> & R;
这也将检查你覆盖的键是否也存在于原始接口中,从而确保如果原始接口更改了名称,那么你将得到编译时错误,你也必须更改名称。
解释:
举个例子。
interface OriginalInterface {
id: string
}
修改后的型号如下图所示
interface ModifiedInterface {
id: number
}
现在,假设在未来,OriginalInterface的id被重命名为uId,然后使用我的类型实用程序,你将得到如下错误
interface ModifiedInterface {
id: number // Type '{ geo_point1: GeoPoint | null; }' has no properties in common with type 'Partial<Address>'.ts(2559)
}