当我使用数组扩展运算符创建新数组时 TypeScript似乎丢失了正确的类型信息。
如果我使用Array.combine()
创建新数组,则不会发生这种情况。
我准备了一个简单的例子来证明这一点。我使用声明合并使常量(ACES
,TWOS
等)具有相应的类型。然后我创建类型Category
为"超类型"。
变量sectionsSpread
在使用数组扩展运算符创建后属于string[]
类型。变量sectionsCombined
的类型为Category[]
。
我预计变量sectionsSpread
也属于Category[]
类型。
这是一个错误吗?我有阵列传播错误吗?
const ACES = 'ACES';
type ACES = typeof ACES;
const TWOS = 'TWOS';
type TWOS = typeof TWOS;
const THREES = 'THREES';
type THREES = typeof THREES;
const FULL_HOUSE = 'FULL_HOUSE';
type FULL_HOUSE = typeof FULL_HOUSE;
const SMALL_STRAIGHT = 'SMALL_STRAIGHT';
type SMALL_STRAIGHT = typeof SMALL_STRAIGHT;
const LARGE_STRAIGHT = 'LARGE_STRAIGHT';
type LARGE_STRAIGHT = typeof LARGE_STRAIGHT;
type Category = ACES | TWOS | THREES |
FULL_HOUSE | SMALL_STRAIGHT | LARGE_STRAIGHT;
const upperSection: Array<Category> = [ACES, TWOS, THREES];
const lowerSection: Array<Category> = [FULL_HOUSE, SMALL_STRAIGHT, LARGE_STRAIGHT];
const sectionsSpread = [
...upperSection,
...lowerSection
];
const sectionsCombined = upperSection.concat(lowerSection);
UDATE
@dbandstra和@basarat指出了我正确的方向。阅读suggested blog post后,我认为我理解文字类型扩展。但是,对于我来说,这仍然无法解释typeof
运营商在此背景下的行为。
我希望以下示例能让我的问题更清晰:
const ACES = 'ACES';
type ACES = 'ACES'; // non-widening literal type
const TWOS = 'TWOS';
type TWOS = 'TWOS'; // non-widening literal type
type Category = ACES | TWOS; // are these values or types?
const upperSection: Category[] = [ACES];
const lowerSection: Category[] = [TWOS];
const sectionsSpread = [
...upperSection,
...lowerSection,
]; // is of type Category[]
如果我使用typeof
,则变量sectionsSpread
最终会变为string[]
类型:
const ACES = 'ACES';
type ACES = typeof ACES; // what does typeof do here?
const TWOS = 'TWOS';
type TWOS = typeof TWOS; // what does typeof do here?
type Category = ACES | TWOS; // are these values or types?
const upperSection: Category[] = [ACES];
const lowerSection: Category[] = [TWOS];
const sectionsSpread = [
...upperSection,
...lowerSection,
]; // is of type string[]
答案 0 :(得分:2)
这是扩大与非扩大。显式注释意味着在分配给其他值时,TypeScript不会更改其含义。
const ACES = 'ACES';
type Category = typeof ACES;
const upperSection: Category[] = [];
const sectionsSpread = [
...upperSection,
]; // string[]
const ACES = 'ACES';
type Category = 'ACES';
const upperSection: Category[] = [];
const sectionsSpread = [
...upperSection,
]; // Category