2016-11-26 4 views
3

Я не понимаю, что такое фактическое использование дженериков в typescirpt.Реальное использование generic в машинописных текстах

interface ICustomer 
{ 
    name: string; 
    age: number; 
} 


function CalcAverageAge<c extends ICustomer>(cust1: c, cust2: c): number 
{ 
    return (cust1.age + cust2.age)/2; 
} 


resNumber = CalcAverageCustomerAge({name: "Peter", age: 62}, 
            {name: "Jason", age: 33}); 

В приведенном выше примере мы передаем интерфейс c функции CalcAverageAge.

Но без использования расширений ICustomer мы не можем использовать возраст и имя внутри этого класса.

Тогда в чем заключается использование шаблона прохождения (c) в функции. Мы можем непосредственно написать код в поле ниже формате

function CalcAverageAge(cust1: ICustomer, cust2: ICustomer): number 
{ 
    return (cust1.age + cust2.age)/2; 
} 

Можете ли вы дать реальный пример, когда дженерики действительно полезно?

Я объясню вам мой сценарий, где мне нужно использовать дженерики.

interface t1{ 
a:String 
b:number 

} 
interface t2 { 
a:String 
b:number 
c:number 
} 
interface t3 { 
a:String 
b:number 
d:number 
} 

class base<T extends t1> { 
    constructor(input : T, type:string){ 

     //some common code for both derived1 and derived2 
     if(type==="derived1"){ 
     console.log(input.c);// will throw error because t1 doesn't contains c 
     } else if (type==="derived2"){ 
      console.log(input.d);// will throw error because t1 doesn't contains d 
     } 
    } 
} 

class derived1 extends<t2>{ 
constructor(){ 
var temp = {a:"11",b:2,c:3} 
super(temp,"derived1"); 
} 
class derived2 extends<t3>{ 
constructor(){ 
var temp = {a:"11",b:2,d:3} 
super(temp,"derived2"); 
} 
} 

Можем ли мы добиться этого с помощью генераторов?

Если нет, то какой был бы лучший способ реализации, избегая дублирования кодов.

+1

В вашем отредактированном вопросе неясно, чего вы хотите достичь. Какова цель этой архитектуры? '.c' и' .d' будут недоступны, поскольку вы не даете классу 'base' любую информацию, указывающую, что эти свойства существуют. Если вы хотите, чтобы эти свойства были доступны, это неправильный дизайн, и нам нужна дополнительная информация о том, что вы на самом деле хотите сделать, чтобы дать вам достойный ответ о том, как его достичь. – Nypan

ответ

1

В вашем примере это правильно, что интерфейс - это все, что вам нужно.

Generics - это то, что полезно, когда вы хотите что-то сделать generic; иногда это может быть настолько общим, что вам даже не нужен интерфейс. Пример, который вы приводите, не только является общим, но и ограничивает то, что общий тип может выглядеть с интерфейсом.

Другие примеры того, что может использоваться для общего типа, это коллекция, которая может содержать любой тип элемента. Например, тип массива в машинописном тексте является примером - var a = new Array<number>().

Но сказать, что вы хотите создать функцию, которая сравнивает два элемента, что-то вроде этого:

interface IValue { value: number; } 

function max(a: IValue, b: IValue): IValue { 
    return a.value > b.value ? a : b; 
} 

В этом случае у вас есть вопрос о том, что функция max возвращает результат как IValue В большинстве случаев это это не то, что вы хотите. То, что вы хотите что-то вроде этого:

interface IValue { value: number; } 

function max<T extends IValue>(a: T, b: T): T { 
    return a.value > b.value ? a : b; 
} 

Здесь возвращаемый тип max является то, что общий тип T есть, и это более полезно.

+0

Этот пример достаточно крут, чтобы иметь представление о дженериках. Но вы согласитесь со мной, когда вы работаете над большим проектом, вы редко получаете с такой простой функциональностью (макс.). Можете ли вы привести мне пример в больших масштабах. – user7131571

+0

Я отредактировал вопрос, пожалуйста, посмотрите. И, пожалуйста, удалите это peer rieview. Это была ошибка. – user7131571

Смежные вопросы