天道酬勤,学无止境

将接口的对象转换为其基接口(Convert an object of an interface to its base interface)

问题
interface IPerson {
    firstName: string;
    lastName:  string;
}

interface IPersonWithPhone extends IPerson {
    phone: string;
}

const personWithPhone: IPersonWithPhone = {
    firstName: "Foo",
    lastName: "Boo",
    phone: "+1 780-123-4567"
}

可以说IPersonWithPhone扩展了IPerson 。 我想将personWithPhone转换为person ,意思是personWithPhone.phone = undefined 。 我不想改变对象,同时我不想单独设置每个属性。 像下面这样,

// Not like this
const person: IPerson = {
    firstName: personWithPhone.firstName,
    lastName: personWithPhone.lastName
}

我正在寻找类似于 spread 的东西,它可以删除属性并可以转换为基本接口。

// example of spread
cont person: IPerson = {
    firstName: "Foo",
    lastName: "Boo",
}

const personWithPhone: IPersonWithPhone = {...person, phone: "+1 780-123-4567"};
回答1

类型信息在运行时不存在,所以这里没有神奇的解决方案。 您需要指定要省略的属性。

选项之一是对象解构:

const personWithPhone: IPersonWithPhone = {
    firstName: "Foo",
    lastName: "Boo",
    phone: "+1 780-123-4567"
}

const { phone, ...person } = personWithPhone;

这里personWithPhone phone属性转到phone变量,其余的都变成了person

标签

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 如何将Object转换为其实际类型?(How to cast Object to its actual type?)
    问题 如果我有: void MyMethod(Object obj) { ... } 如何将obj转换为实际类型? 回答1 如果您知道实际的类型,则只需: SomeType typed = (SomeType)obj; typed.MyFunction(); 如果您不知道实际的类型,那么:不是,不是。 您将不得不使用以下之一: 反射实现一个众所周知的接口动态的 例如: // reflection obj.GetType().GetMethod("MyFunction").Invoke(obj, null); // interface IFoo foo = (IFoo)obj; // where SomeType : IFoo and IFoo declares MyFunction foo.MyFunction(); // dynamic dynamic d = obj; d.MyFunction(); 回答2 我认为您可以(并非没有反思),也应该为您的函数提供一种类型: void MyMethod(Object obj, Type t) { var convertedObject = Convert.ChangeType(obj, t); ... } UPD : 这可能对您有用: void MyMethod(Object obj) { if (obj is A) { A a =
  • 接口上用于强制一致性的静态方法的替代方法(Alternatives to static methods on interfaces for enforcing consistency)
    问题 在Java中,我希望能够定义标记器接口,该标记器接口强制实现提供静态方法。 例如,对于简单的文本序列化/反序列化,我希望能够定义一个看起来像这样的接口: public interface TextTransformable<T>{ public static T fromText(String text); public String toText(); 但是,由于Java中的接口不能包含静态方法(如其他许多帖子/线程中所述:此处,此处和此处,此代码不起作用。 但是,我正在寻找一种表达相同意图的合理范例,即对称方法,其中之一是静态的,由编译器强制执行。 现在,我们能想到的最好的方法是某种静态工厂对象或通用工厂,这两种方法都不能令人满意。 注意:在我们的例子中,我们的主要用例是我们有很多“价值对象”类型-枚举或其他价值有限的对象,通常不携带超出其价值的状态,我们对其进行解析/解析-每秒解析数千次,因此实际上要关心重用实例(例如Float,Integer等)及其对内存消耗/ gc的影响 有什么想法吗? EDIT1:为了消除一些混乱-我们有许多不同的对象适合此模式-确实,我们尝试为调用者提供2种语义的优雅的东西: 作为合同的接口-访问的统一性(例如TextTransformable作为一种功能) 要求子类/实现的实现(例如,强迫他们实现自己的转换 就我们对Flyweight
  • 接口定义构造函数签名?(Interface defining a constructor signature?)
    问题 很奇怪,这是我第一次遇到这个问题,但是: 如何在C#接口中定义构造函数? 编辑有些人想要一个例子(这是一个业余时间项目,所以是的,这是一个游戏) IDrawable +更新 +抽奖 为了能够更新(检查屏幕边缘等)并绘制自身,它将始终需要GraphicsDeviceManager 。 因此,我想确保该对象具有对它的引用。 这将属于构造函数。 既然我写下来了,我认为我在这里实现的是IObservable ,而GraphicsDeviceManager应该采用IDrawable ……似乎我没有XNA框架,或者该框架没有被很好地考虑。 编辑我在接口上下文中对构造函数的定义似乎有些困惑。 接口确实无法实例化,因此不需要构造函数。 我想定义的是构造函数的签名。 就像接口可以定义某种方法的签名一样,接口可以定义构造函数的签名。 回答1 如前所述,接口上不能有构造函数。 但是,由于这是大约7年后在Google中排名靠前的结果,所以我想在这里介绍一下-专门说明如何使用抽象基类与现有的Interface并用,并可能减少重构量将来在类似情况下也需要。 在一些评论中已经暗示了这个概念,但是我认为值得展示如何实际执行。 到目前为止,您的主界面如下所示: public interface IDrawable { void Update(); void Draw(); } 现在
  • 在JSON.NET中强制转换反序列化的接口(Casting interfaces for deserialization in JSON.NET)
    问题 我正在尝试建立一个读取器,该读取器将从各种网站中接收JSON对象(考虑信息抓取)并将其转换为C#对象。 我目前正在使用JSON.NET进行反序列化过程。 我遇到的问题是它不知道如何处理类中的接口级属性。 所以自然的东西: public IThingy Thing 会产生错误: 无法创建类型为IThingy的实例。 类型是接口或抽象类,无法实例化。 相对于Thingy,让它成为IThingy相对重要,因为我正在处理的代码被认为是敏感的,并且单元测试非常重要。 对于像Thingy这样的成熟对象,无法为原子测试脚本模拟对象。 它们必须是接口。 我已经浏览JSON.NET的文档已有一段时间了,而我在此站点上可以找到的与此相关的问题都是一年多以前的。 有什么帮助吗? 另外,如果有关系,我的应用程序是用.NET 4.0编写的。 回答1 @SamualDavis在一个相关的问题中提供了一个很好的解决方案,我将在这里进行总结。 如果必须将JSON流反序列化为具有接口属性的具体类,则可以将具体类作为参数包含在该类的构造函数中! NewtonSoft反序列化器足够聪明,可以弄清楚它需要使用那些具体的类来反序列化属性。 这是一个例子: public class Visit : IVisit { /// <summary> /// This constructor is required for
  • 如何将对象从其基类转换为其子类(How to cast an object from its base class into its subclass)
    问题 我有一个User类,它是PFUser类的子类: class User: PFUser { var isManager = false } 在我的一种方法中,我收到了一个PFUser对象,我想将它转换为一个User对象 func signUpViewController(signUpController: PFSignUpViewController!, didSignUpUser user: PFUser!) { currentUser = user } 这可能吗? 回答1 如果它是PFUser的实例,而不是存储在PFUser类型变量中的User实例,则不可能。 您可以将类的实例强制转换为其超类之一,但不能以其他方式执行(除非强制转换类型是实际的实例类型)。 我建议在User实现一个初始化程序,将PFUser实例作为参数 - 如果可能的话。 然而,虽然我从未尝试这样做,但我认为从PFUser继承你会遇到麻烦,因为我的理解是这个类不是为了继承而设计的,因为它是PFObject 。 我建议寻找到制作PFUser的属性User -这样您可以根据需要分配公正。 回答2 这种类型的铸造是一种沮丧。 鉴于在那里你知道存在的子类的一定基础类的实例,你可以尝试用类型转换操作者垂头丧气as : class Base {} class Derived : Base {} let base
  • 无法将派生类型隐式转换为其基本泛型类型(Cannot implicitly convert derived type to its base generic type)
    问题 我有以下类和接口: public interface IThing { string Name { get; } } public class Thing : IThing { public string Name { get; set; } } public abstract class ThingConsumer<T> where T : IThing { public string Name { get; set; } } 现在,我有一个工厂,它将返回从ThingConsumer派生的对象,例如: public class MyThingConsumer : ThingConsumer<Thing> { } 我的工厂目前看起来像这样: public static class ThingConsumerFactory<T> where T : IThing { public static ThingConsumer<T> GetThingConsumer(){ if (typeof(T) == typeof(Thing)) { return new MyThingConsumer(); } else { return null; } } } 我因以下错误而绊倒: Error 1 Cannot implicitly convert type
  • 为什么(确实吗?)列表实现所有这些接口,而不仅仅是IList ?(Why does (does it really?) List<T> implement all these interfaces, not just IList<T>?)
    问题 来自MSDN的List声明: public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable 反射镜给出相似的图像。 List是否真的实现了所有这些功能(如果是,为什么)? 我检查过: interface I1 {} interface I2 : I1 {} interface I3 : I2 {} class A : I3 {} class B : I3, I2, I1 {} static void Main(string[] args) { var a = new A(); var a1 = (I1)a; var a2 = (I2)a; var a3 = (I3)a; var b = new B(); var b1 = (I1) b; var b2 = (I2)b; var b3 = (I3)b; } 它编译。 [更新]: 伙计们,据我所知,所有答复都保持不变: class Program { interface I1 {} interface I2 : I1 {} interface I3 : I2 {} class A : I3 {} class B : I3, I2, I1 {} static void I1M(I1 i1) {}
  • 为什么Array不是泛型类型?(Why isn't Array a generic type?)
    问题 Array声明为: public abstract class Array : ICloneable, IList, ICollection, IEnumerable { 我想知道为什么不是这样: public partial class Array<T> : ICloneable, IList<T>, ICollection<T>, IEnumerable<T> { 如果将其声明为泛型类型,将会有什么问题? 如果它是泛型类型,我们是否仍需要非泛型类型,还是可以从Array<T>派生呢? 如public partial class Array: Array<object> { 回答1 历史 如果数组成为泛型类型会出现什么问题? 回到C#1.0中,他们主要从Java复制了数组的概念。 泛型当时不存在,但是创建者认为它们很聪明,并复制了Java数组具有的破碎的协变量数组语义。 这意味着您可以完成这样的事情而没有编译时错误(而是运行时错误): Mammoth[] mammoths = new Mammoth[10]; Animal[] animals = mammoths; // Covariant conversion animals[1] = new Giraffe(); // Run-time exception 在C#2.0中引入了泛型,但没有协变/相反的泛型类型。
  • 如何转换为对象可能实现的接口?(How do I cast to an interface an object may implement?)
    问题 我有以下类和接口: export interface IBody { body : ListBody; } export class Element { // ... } export class Paragraph extends Element implements IBody { // ... } export class Character extends Element { // ... } 我有代码,我将在其中获取元素派生对象的数组(不仅仅是段落和字符)。 对于那些实现 IBody 的情况,我需要对 body 中的元素采取行动。 查看它是否实现 IBody 的最佳方法是什么? 是“if (element.body !== undefined)”吗? 然后我如何访问它? “var bodyElement = <IBody> 元素;” 给我一个错误。 C:/src/jenova/Dev/Merge/AutoTagWeb/client/layout/document/elements/factory.ts(34,27): error TS2012: Cannot convert 'Element' to 'IBody': Type 'Element' is missing property 'body' from type 'IBody'. Type 'IBody'
  • 无法将数据(类型接口{})转换为字符串类型:需要类型断言(cannot convert data (type interface {}) to type string: need type assertion)
    问题 我要走的很新,我正在玩这个通知包。 最初,我有如下代码: func doit(w http.ResponseWriter, r *http.Request) { notify.Post("my_event", "Hello World!") fmt.Fprint(w, "+OK") } 我想在Hello World!后面添加换行符Hello World! 但不是在上面的函数doit ,因为那将是微不足道的,但是在随后的handler ,如下所示: func handler(w http.ResponseWriter, r *http.Request) { myEventChan := make(chan interface{}) notify.Start("my_event", myEventChan) data := <-myEventChan fmt.Fprint(w, data + "\n") } go run : $ go run lp.go # command-line-arguments ./lp.go:15: invalid operation: data + "\n" (mismatched types interface {} and string) 经过一番谷歌搜索后,我在SO上发现了这个问题。 然后,我将代码更新为: func handler(w
  • 为什么.NET值类型是密封的?(Why are .NET value types sealed?)
    问题 无法从C#结构继承。 对我来说,这不是很明显: 显然,您不能拥有从值类型继承的引用类型。 这行不通从一种原始类型(Int32,Double,Char等)继承似乎很不合理。 您需要能够使用派生实例在基础上调用(非虚拟)方法。 您可以将其从派生结构转换为基本结构,因为它们会重叠相同的内存。 我猜从基础转换为派生类是行不通的,因为您在运行时不知道派生结构的类型。 我可以看到您无法在类层次结构中实现虚拟方法,因为值类型不能具有虚拟成员 我想知道这是否是CLR中的技术限制,还是C#编译器阻止您执行某些操作? 编辑:值类型不能有虚拟方法,并且我意识到此限制排除了您要使用继承的大多数情况。 但是,仍然保留继承即聚合。 想象一下带有Colour字段的Shape结构:即使我永远无法编写虚拟Shape.Draw方法,我也可以编写代码来接受任何从Shape派生的结构,并访问其Colour字段。 我可以想到一种可能会被非密封的值类型破坏的情况。 值类型应该正确实现Equals和GetHashCode ; 即使System.Object上的这两种方法是虚拟的,它们也都在值类型上被非虚拟地调用。 即使没有密封值类型,编写从另一个结构派生的结构的人也无法编写自己的这两种方法的实现,并期望正确调用它们。 我应该指出,我并不是说我应该能够在自己的代码中从结构继承。 不过,我试图做的是猜测为什么
  • 在 C# 中使用“类型”对象对对象进行类型转换(Type Casting an Object using a “Type” Object in C#)
    问题 到目前为止,事实证明这个对我来说有点棘手。 我想知道是否可以使用 System.Type 对象对对象进行类型转换。 我在下面说明了我的意思: public interface IDataAdapter { object Transform(object input); Type GetOutputType(); } public class SomeRandomAdapter : IDataAdapter { public object Transform(object input) { string output; // Do some stuff to transform input to output... return output; } public Type GetOutputType() { return typeof(string); } } // Later when using the above methods I would like to be able to go... var output = t.Transform(input) as t.GetOutputType(); 以上是一个通用接口,这就是为什么我使用“对象”作为类型。 回答1 这样做的典型方法是使用泛型,如下所示: public T2 Transform<T, T2>(T input
  • 如何将接口转换为 Typescript 中的映射类型(How to convert interface to mapped type in Typescript)
    问题 背景 在映射类型的打字稿文档中,给出了以下示例: type Proxy<T> = { get(): T; set(value: T): void; } type Proxify<T> = { [P in keyof T]: Proxy<T[P]>; } function proxify<T>(o: T): Proxify<T> { // ... wrap proxies ... } let proxyProps = proxify(props); 我不清楚我将如何编写代理函数。 我需要它做什么 我有以下类型 interface User extends BaseRecord { readonly 'id': number; readonly 'name'?: string; } interface FormField<T> { readonly value: T; readonly edited: boolean; } type WrappedInFormField<T> = { [P in keyof T]: FormField<T[P]>; }; 我需要写一个具有以下签名的函数 const wrap = <T>(o: T): WrappedInFormField<T> => { // ...What goes here?... } wrappedUser
  • 接口和类之间的转换(Casting between Interfaces and Classes)
    问题 昨天我刚开始学习接口,一直在做一些简单的例子,我注意到我在理解类和接口之间的转换时遇到了很多麻烦,所以我阅读了 Java Cast Interface to Class 以及 Interfaces Oracle Java Tutorials 但是当我的书在底部给出了一个小小的评论问题时,我发现我仍然没有真正完全理解,而且我买的书没有解决方案。 以下是问题(我给出了我的尝试和推理,这对某些人来说可能是错误的,所以任何帮助都是好的!) 假设 Sandwich 类实现了 Edible 接口,并且你得到了变量声明 Sandwich sub = new Sandwich(); Rectangle cerealBox = new Rectangle(5, 10, 20, 30); Edible e = null; 以下哪些赋值语句是合法的? e = sub; 由于 Sandwich 类实现了Edible接口,所以这没有问题。 我们可以说e = sub没有问题。 有用sub = e; 由于我们试图将Sandwitch类中的对象sub更改为interface类型,因此我们无法在不进行转换的情况下做到这一点。 它不会工作sub = (Sandwich) e 有效! 这解决了我们的老问题sub = (Sandwich) cerealBox; 我不知道..但它应该工作吗?
  • WPF数据绑定到接口而不是实际对象-是否可以强制转换?(WPF databinding to interface and not actual object - casting possible?)
    问题 说我有一个像这样的界面: public interface ISomeInterface { ... } 我也有几个实现此接口的类。 public class SomeClass : ISomeInterface { ... } 现在,我有了一个使用自定义DataTemplate列出ISomeInterface项的WPF ListBox。 数据绑定引擎显然不允许(我已经能够弄清楚)允许我绑定到接口属性-它看到该对象是SomeClass对象,并且仅当SomeClass应该碰巧具有bounded属性时才显示数据。非接口属性。 我怎样才能告诉DataTemplate像每个对象都是一个ISomeInterface而不是SomeClass一样工作? 谢谢! 回答1 为了绑定到显式实现的接口成员,您需要做的就是使用括号。 例如: 隐式的: {Binding Path=MyValue} 明确的: {Binding Path=(mynamespacealias:IMyInterface.MyValue)} 回答2 Beatriz Costa-MSFT在Microsoft论坛上提供的以下答案值得一读(比较旧): 数据绑定团队不久前讨论了添加对接口的支持,但最终没有实现它,因为我们无法为其提供良好的设计。 问题在于接口没有像对象类型那样的层次结构。 考虑以下场景
  • 为什么我不能将此接口转换为具体类?(Why can't I cast this interface to a concrete class?)
    问题 我有一个接口IApiDataWithProperties 。 一个叫做Event的类实现了这个接口。 通常我可以将IApiDataWithProperties的对象IApiDataWithProperties为Event (假设它是一个)并且编译器让我这样做没问题。 在这种情况下,该类型实际上是一个通用的TApiData ,它对接口IApiDataWithProperties有where限制。 但是,即使有类型限制,我也无法将TApiData为Event 。 我得到Cannot convert type 'TApiData' to 'Event' 为什么是这样? 我错过了什么吗? public class Event : IApiDataWithProperties, IXmlSerializable { // ... } public abstract class AbstractBatchPropertyProcessor<TApiData> : AbstractBatchProcessor<TApiData>, IBatchProcessor where TApiData : IApiDataWithProperties { protected virtual string Build(ConcurrentBag<TApiData> batch) { foreach
  • 给定C#类型,获取其基类和已实现的接口(Given a C# Type, Get its Base Classes and Implemented Interfaces)
    问题 我正在使用C#开发游戏引擎。 我正在研究的类称为CEntityRegistry ,其工作是跟踪游戏中CEntity的许多实例。 我的目标是能够查询给定类型的CEntityRegistry ,并获取该类型的每个CEntity的列表。 因此,我想做的就是维护一张地图: private IDictionary<Type, HashSet<CEntity>> m_TypeToEntitySet; 然后更新注册表: private void m_UpdateEntityList() { foreach (CEntity theEntity in m_EntitiesToRemove.dequeueAll()) { foreach (HashSet<CEntity> set in m_TypeToEntitySet.Values) { if (set.Contains(theEntity)) set.Remove(theEntity); } } foreach (CEntity theEntity in m_EntitiesToAdd.dequeueAll()) { Type entityType = theEntity.GetType(); foreach (Type baseClass in entityType.GetAllBaseClassesAndInterfaces()) m
  • Java中的标记接口?(Marker Interfaces in Java?)
    问题 有人告诉我,Java中的Marker接口是一个空接口,用于向编译器或JVM发出信号,必须以特殊方式处理实现此接口的类的对象,例如序列化,克隆等。 但是最近我了解到它实际上与编译器或JVM无关。 例如,对于Serializable接口, ObjectOutputStream writeObject(Object)方法执行类似于instanceOf Serializable以检测该类是否实现Serializable并相应地引发NotSerializableException 。 一切都在代码中处理,这似乎是一种设计模式,所以我认为我们可以定义自己的标记接口。 现在我的疑问: 上面第一点提到的标记接口的定义是否错误? 那么我们如何定义Marker接口呢? 并且为什么不使用instanceOf运算符,为什么不能将方法设为类似writeObject(Serializable)这样的方法,以便进行编译时类型检查而不是运行时检查? 注释比标记接口更好吗? 回答1 上面第一点提到的标记接口的定义是否错误? -在以下部分中是正确的:(1)标记接口必须为空,并且(2)实现该接口意味着要对实现类进行某些特殊处理。 不正确的部分是,这意味着JVM或编译器将以不同的方式对待该类的对象:您正确地观察到是Java类库的代码将这些对象视为可克隆,可序列化等。与编译器或JVM无关。
  • PHP具有接口的多重继承(PHP Multiple Inheritance with Interfaces)
    问题 我试图了解使用接口如何在我一直在使用谷歌搜索的情况下赋予我多重继承。 class A { function do1(){} function do2(){} function do3(){} } class B extends A { function do4(){} function do5(){} function do6(){} } class C extends B { } 在上面的示例中,类C具有类A和B中的所有方法。但是,类B也具有类A中的所有方法,这不是必需的。 我的搜索结果是使用接口通过将方法移至类并创建接口来解决此问题,如下所示。 interface A { function do1(); function do2(); function do3(); } interface B { function do4(); function do5(); function do6(); } class C implements A, B { function do1(){} function do2(){} function do3(){} function do4(){} function do5(){} function do6(){} } 我真的看不出这是如何解决问题的,因为所有代码都在新类中。 如果我只是想像最初那样使用类A
  • “任何”与“对象”('any' vs 'Object')
    问题 我正在查看TypeScript代码,并注意到它们使用了: interface Blablabla { field: Object; } 使用Object与any什么好处,例如: interface Blablabla { field: any; } 回答1 Object比any Object都更具限制性。 例如: let a: any; let b: Object; a.nomethod(); // Transpiles just fine b.nomethod(); // Error: Property 'nomethod' does not exist on type 'Object'. Object类没有nomethod()函数,因此编译器将生成一条错误消息,告诉您确切的信息。 如果您改用any ,则基本上是在告诉编译器一切正常,您没有提供有关存储在-中a -它可以是任何信息! 因此,编译器将允许您使用定义为any东西做您想做的any事情。 简而言之 any可以是任何东西(您可以在其上调用任何方法等,而不会发生编译错误) Object公开Object类中定义的功能和属性。 回答2 有点老了,但是添加一些笔记并没有什么坏处。 当你写这样的东西 let a: any; let b: Object; let c: {}; a没有接口,可以是任何接口,编译器对其成员一无所知