Angular/TS技术问题:如何从部分继承的接口中获取属性值?
Hey there! Let's work through this together since you're new to Angular and TypeScript—no worries, this is a common question when starting out with type inheritance and service data sharing.
First, let's fix a small bug in your CustomerService that might trip you up later: in the getCustomers method, you're referencing customers instead of this.customers. That'll cause an undefined variable error, so let's correct that first:
export class CustomerService { customers: CustomerModel[]; constructor() { this.customers = [{ firstName: 'John', lastName: 'Doe', // Your other properties here }, { firstName: 'Jane', lastName: 'Smith', // Your other properties here }]; } getCustomers(): Observable<CustomerModel[]> { // Use `this.customers` to reference the service's property return of(this.customers); } }
Now, onto your main question: TypeScript's Pick utility only defines the shape of your OrderModel (it tells TypeScript that OrderModel should have firstName and lastName with the same types as CustomerModel). It doesn't automatically populate those values for you—you need to explicitly pull them from your existing customer data.
Since you're in a local hardcoding phase, the cleanest way is to inject your CustomerService into OrderService and reuse the customer data you've already defined. Here's how to do that:
import { Injectable } from '@angular/core'; import { of, Observable } from 'rxjs'; import { OrderModel } from './your-interfaces-path'; // Update this path import { CustomerService } from './customer.service'; // Update this path @Injectable({ providedIn: 'root' }) export class OrderService { orders: OrderModel[]; // Inject CustomerService to access its customer data constructor(private customerService: CustomerService) { // Grab the hardcoded customers from CustomerService const customers = this.customerService.customers; // Option 1: Generate an order for every customer (quick, consistent) this.orders = customers.map((customer, index) => ({ orderNumber: 123 + index, // Unique order number per customer firstName: customer.firstName, // Pull directly from customer lastName: customer.lastName })); // Option 2: Manually create orders linked to specific customers (for custom orders) // this.orders = [ // { // orderNumber: 123, // // Link to the first customer in your list // firstName: customers[0].firstName, // lastName: customers[0].lastName // }, // { // orderNumber: 124, // // Link to the second customer // firstName: customers[1].firstName, // lastName: customers[1].lastName // } // ]; } getOrders(): Observable<OrderModel[]> { return of(this.orders); } }
Key Notes:
- Dependency Injection: By injecting
CustomerService, you avoid duplicating customer data across services—this keeps your code DRY (Don't Repeat Yourself) and ensures consistency if you ever update the customer details later. - Type Safety: TypeScript will still enforce that
firstNameandlastNamematch the types fromCustomerModel, so you don't have to worry about mismatched data types. - Future-Proofing: When you switch to a database later, you can adjust this pattern to fetch customers via
customerService.getCustomers()(using RxJS operators likemaporswitchMapto generate orders from the observable customer data) instead of using the hardcodedcustomersarray directly.
Just make sure your CustomerService is marked with @Injectable({ providedIn: 'root' }) (like the OrderService above) so Angular can inject it properly.
内容的提问来源于stack exchange,提问作者Siobhan Holubicka

