2015-11-03 2 views
1

Я хочу написать функцию, которая задает массив, удаляет из нее повторяющиеся элементы. Я хотел бы, чтобы эта функция работала как минимум на число и строку. Моя попытка:Тип функции, которая удаляет дубликаты в TypeScript

function removeDuplicates<T>(xs: T[]): T[] 
{ 
    var res: T[] = []; 
    var seen = {}; 
    for (var i = 0; i < xs.length; i++) { 
     var x = xs[i]; 
     if (!(x in seen)) { 
      seen[x] = null; 
      res.push(xs[i]); 
     } 
    } 
    return res; 
} 

Которую действительный Javascript для удаления элементов (после удаления типов). Однако, в машинописном, я получаю ошибку на in линии говоря:

Левая сторона «в» выражение должно быть типа «любой», «строка», «число», или ' символ'.

Я пробовал T extends string | number, но это не работает. Я думал о T is string | number, но я не могу найти синтаксис TypeScript для этого. Как я могу захватить это свойство в типе?

+2

TS дает вам красный флаг здесь должным образом, потому что вашей реализации может стать неправильным, я полагаю. Вы не можете иметь объект в качестве ключа другого объекта. если вы это сделаете, он просто преобразует объект в его строковое представление [object Object]. Таким образом, ваша общая логика здесь не будет работать, это T - объект, я имею в виду, что сама функциональность сломается. Тем не менее, если вы хотите просто сделать TS счастливым, вы можете сделать var x: any = xs [i]; но это не решит цель. – PSL

ответ

3

Одно из решений заключается в использовании явного аннотацию типа any:

function removeDuplicates<T>(xs: T[]): T[] 
{ 
    var res: T[] = []; 
    var seen = {}; 
    for (var i = 0; i < xs.length; i++) { 
     var x:any = xs[i]; 
     if (!(x in seen)) { 
      seen[x] = null; 
      res.push(xs[i]); 
     } 
    } 
    return res; 
} 

я дополнительно рекомендую явно применяя string|number ограничение:

type ValidKey = string|number; 
function removeDuplicates<T extends ValidKey>(xs: T[]): T[] 
{ 
    var res: T[] = []; 
    var seen = {}; 
    for (var i = 0; i < xs.length; i++) { 
     var x:ValidKey = xs[i]; 
     if (!(x in seen)) { 
      seen[x] = null; 
      res.push(xs[i]); 
     } 
    } 
    return res; 
} 

removeDuplicates(['a','b','a']) // okay 
removeDuplicates([1,2]) // okay 
removeDuplicates([{a:1},{a:2}]) // Not cool 
+0

Есть ли способ указать ограничение на 'T' с помощью TypScript? – PSL

+1

@PSL Сделано в обновлении – basarat

+1

Awesome ... Я многому учусь из ваших ответов. Спасибо, +1! :) – PSL

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