TypeScript/tests/baselines/reference/recursiveTypeReferences1.types
Daniel Rosenwasser cce4bfbc7c
Revert changes for template literal types, keeping tests. (#42588)
* Revert changes for template literal types, keeping tests.

* Update Baselines and/or Applied Lint Fixes

Co-authored-by: TypeScript Bot <typescriptbot@microsoft.com>
2021-02-03 14:49:03 -08:00

611 lines
20 KiB
Plaintext

=== tests/cases/conformance/types/typeRelationships/recursiveTypes/recursiveTypeReferences1.ts ===
type ValueOrArray<T> = T | Array<ValueOrArray<T>>;
>ValueOrArray : ValueOrArray<T>
const a0: ValueOrArray<number> = 1;
>a0 : ValueOrArray<number>
>1 : 1
const a1: ValueOrArray<number> = [1, [2, 3], [4, [5, [6, 7]]]];
>a1 : ValueOrArray<number>
>[1, [2, 3], [4, [5, [6, 7]]]] : (number | (number | (number | number[])[])[])[]
>1 : 1
>[2, 3] : number[]
>2 : 2
>3 : 3
>[4, [5, [6, 7]]] : (number | (number | number[])[])[]
>4 : 4
>[5, [6, 7]] : (number | number[])[]
>5 : 5
>[6, 7] : number[]
>6 : 6
>7 : 7
type HypertextNode = string | [string, { [key: string]: unknown }, ...HypertextNode[]];
>HypertextNode : HypertextNode
>key : string
const hypertextNode: HypertextNode =
>hypertextNode : HypertextNode
["div", { id: "parent" },
>["div", { id: "parent" }, ["div", { id: "first-child" }, "I'm the first child"], ["div", { id: "second-child" }, "I'm the second child"] ] : [string, { id: string; }, [string, { id: string; }, string], [string, { id: string; }, string]]
>"div" : "div"
>{ id: "parent" } : { id: string; }
>id : string
>"parent" : "parent"
["div", { id: "first-child" }, "I'm the first child"],
>["div", { id: "first-child" }, "I'm the first child"] : [string, { id: string; }, string]
>"div" : "div"
>{ id: "first-child" } : { id: string; }
>id : string
>"first-child" : "first-child"
>"I'm the first child" : "I'm the first child"
["div", { id: "second-child" }, "I'm the second child"]
>["div", { id: "second-child" }, "I'm the second child"] : [string, { id: string; }, string]
>"div" : "div"
>{ id: "second-child" } : { id: string; }
>id : string
>"second-child" : "second-child"
>"I'm the second child" : "I'm the second child"
];
type Json = string | number | boolean | null | Json[] | { [key: string]: Json };
>Json : Json
>null : null
>key : string
let data: Json = {
>data : Json
>{ caption: "Test", location: { x: 10, y: 20 }, values: [true, [10, 20], null]} : { caption: string; location: { x: number; y: number; }; values: (true | number[] | null)[]; }
caption: "Test",
>caption : string
>"Test" : "Test"
location: { x: 10, y: 20 },
>location : { x: number; y: number; }
>{ x: 10, y: 20 } : { x: number; y: number; }
>x : number
>10 : 10
>y : number
>20 : 20
values: [true, [10, 20], null]
>values : (true | number[] | null)[]
>[true, [10, 20], null] : (true | number[] | null)[]
>true : true
>[10, 20] : number[]
>10 : 10
>20 : 20
>null : null
};
interface Box<T> { value: T };
>value : T
type T1 = Box<T1>;
>T1 : T1
type T2 = Box<Box<T2>>;
>T2 : T2
type T3 = Box<Box<Box<T3>>>;
>T3 : T3
function f1(t1: T1, t2: T2, t3: T3) {
>f1 : (t1: T1, t2: T2, t3: T3) => void
>t1 : T1
>t2 : T2
>t3 : T3
t1 = t2;
>t1 = t2 : T2
>t1 : T1
>t2 : T2
t1 = t3;
>t1 = t3 : T3
>t1 : T1
>t3 : T3
t2 = t1;
>t2 = t1 : T1
>t2 : T2
>t1 : T1
t2 = t3;
>t2 = t3 : T3
>t2 : T2
>t3 : T3
t3 = t1;
>t3 = t1 : T1
>t3 : T3
>t1 : T1
t3 = t2;
>t3 = t2 : T2
>t3 : T3
>t2 : T2
}
type Box1 = Box<Box1> | number;
>Box1 : Box1
const b10: Box1 = 42;
>b10 : Box1
>42 : 42
const b11: Box1 = { value: 42 };
>b11 : Box1
>{ value: 42 } : { value: number; }
>value : number
>42 : 42
const b12: Box1 = { value: { value: { value: 42 }}};
>b12 : Box1
>{ value: { value: { value: 42 }}} : { value: { value: { value: number; }; }; }
>value : { value: { value: number; }; }
>{ value: { value: 42 }} : { value: { value: number; }; }
>value : { value: number; }
>{ value: 42 } : { value: number; }
>value : number
>42 : 42
type Box2 = Box<Box2 | number>;
>Box2 : Box2
const b20: Box2 = 42; // Error
>b20 : Box2
>42 : 42
const b21: Box2 = { value: 42 };
>b21 : Box2
>{ value: 42 } : { value: number; }
>value : number
>42 : 42
const b22: Box2 = { value: { value: { value: 42 }}};
>b22 : Box2
>{ value: { value: { value: 42 }}} : { value: { value: { value: number; }; }; }
>value : { value: { value: number; }; }
>{ value: { value: 42 }} : { value: { value: number; }; }
>value : { value: number; }
>{ value: 42 } : { value: number; }
>value : number
>42 : 42
type RecArray<T> = Array<T | RecArray<T>>;
>RecArray : RecArray<T>
declare function flat<T>(a: RecArray<T>): Array<T>;
>flat : <T>(a: RecArray<T>) => Array<T>
>a : RecArray<T>
declare function flat1<T>(a: Array<T | Array<T>>): Array<T>
>flat1 : <T>(a: Array<T | Array<T>>) => Array<T>
>a : (T | T[])[]
declare function flat2<T>(a: Array<T | Array<T | Array<T>>>): Array<T>;
>flat2 : <T>(a: Array<T | Array<T | Array<T>>>) => Array<T>
>a : (T | (T | T[])[])[]
flat([1, [2, [3]]]); // number[]
>flat([1, [2, [3]]]) : number[]
>flat : <T>(a: RecArray<T>) => T[]
>[1, [2, [3]]] : (number | (number | number[])[])[]
>1 : 1
>[2, [3]] : (number | number[])[]
>2 : 2
>[3] : number[]
>3 : 3
flat([[[0]]]); // number[]
>flat([[[0]]]) : number[]
>flat : <T>(a: RecArray<T>) => T[]
>[[[0]]] : number[][][]
>[[0]] : number[][]
>[0] : number[]
>0 : 0
flat([[[[[[[[[[[4]]]]]]]]]]]); // number[]
>flat([[[[[[[[[[[4]]]]]]]]]]]) : number[]
>flat : <T>(a: RecArray<T>) => T[]
>[[[[[[[[[[[4]]]]]]]]]]] : number[][][][][][][][][][][]
>[[[[[[[[[[4]]]]]]]]]] : number[][][][][][][][][][]
>[[[[[[[[[4]]]]]]]]] : number[][][][][][][][][]
>[[[[[[[[4]]]]]]]] : number[][][][][][][][]
>[[[[[[[4]]]]]]] : number[][][][][][][]
>[[[[[[4]]]]]] : number[][][][][][]
>[[[[[4]]]]] : number[][][][][]
>[[[[4]]]] : number[][][][]
>[[[4]]] : number[][][]
>[[4]] : number[][]
>[4] : number[]
>4 : 4
flat([1, 'a', [2]]); // (string | number)[]
>flat([1, 'a', [2]]) : (string | number)[]
>flat : <T>(a: RecArray<T>) => T[]
>[1, 'a', [2]] : (string | number | number[])[]
>1 : 1
>'a' : "a"
>[2] : number[]
>2 : 2
flat([1, [2, 'a']]); // (string | number)[]
>flat([1, [2, 'a']]) : (string | number)[]
>flat : <T>(a: RecArray<T>) => T[]
>[1, [2, 'a']] : (number | (string | number)[])[]
>1 : 1
>[2, 'a'] : (string | number)[]
>2 : 2
>'a' : "a"
flat([1, ['a']]); // Error
>flat([1, ['a']]) : string[]
>flat : <T>(a: RecArray<T>) => T[]
>[1, ['a']] : (number | string[])[]
>1 : 1
>['a'] : string[]
>'a' : "a"
flat1([1, [2, [3]]]); // (number | number[])[]
>flat1([1, [2, [3]]]) : (number | number[])[]
>flat1 : <T>(a: (T | T[])[]) => T[]
>[1, [2, [3]]] : (number | (number | number[])[])[]
>1 : 1
>[2, [3]] : (number | number[])[]
>2 : 2
>[3] : number[]
>3 : 3
flat1([[[0]]]); // number[][]
>flat1([[[0]]]) : number[][]
>flat1 : <T>(a: (T | T[])[]) => T[]
>[[[0]]] : number[][][]
>[[0]] : number[][]
>[0] : number[]
>0 : 0
flat1([1, 'a', [2]]); // (string | number)[]
>flat1([1, 'a', [2]]) : (string | number)[]
>flat1 : <T>(a: (T | T[])[]) => T[]
>[1, 'a', [2]] : (string | number | number[])[]
>1 : 1
>'a' : "a"
>[2] : number[]
>2 : 2
flat1([1, [2, 'a']]); // (string | number)[]
>flat1([1, [2, 'a']]) : (string | number)[]
>flat1 : <T>(a: (T | T[])[]) => T[]
>[1, [2, 'a']] : (number | (string | number)[])[]
>1 : 1
>[2, 'a'] : (string | number)[]
>2 : 2
>'a' : "a"
flat1([1, ['a']]); // Error
>flat1([1, ['a']]) : string[]
>flat1 : <T>(a: (T | T[])[]) => T[]
>[1, ['a']] : (number | string[])[]
>1 : 1
>['a'] : string[]
>'a' : "a"
flat2([1, [2, [3]]]); // number[]
>flat2([1, [2, [3]]]) : number[]
>flat2 : <T>(a: (T | (T | T[])[])[]) => T[]
>[1, [2, [3]]] : (number | (number | number[])[])[]
>1 : 1
>[2, [3]] : (number | number[])[]
>2 : 2
>[3] : number[]
>3 : 3
flat2([[[0]]]); // number[]
>flat2([[[0]]]) : number[]
>flat2 : <T>(a: (T | (T | T[])[])[]) => T[]
>[[[0]]] : number[][][]
>[[0]] : number[][]
>[0] : number[]
>0 : 0
flat2([1, 'a', [2]]); // (string | number)[]
>flat2([1, 'a', [2]]) : (string | number)[]
>flat2 : <T>(a: (T | (T | T[])[])[]) => T[]
>[1, 'a', [2]] : (string | number | number[])[]
>1 : 1
>'a' : "a"
>[2] : number[]
>2 : 2
flat2([1, [2, 'a']]); // (string | number)[]
>flat2([1, [2, 'a']]) : (string | number)[]
>flat2 : <T>(a: (T | (T | T[])[])[]) => T[]
>[1, [2, 'a']] : (number | (string | number)[])[]
>1 : 1
>[2, 'a'] : (string | number)[]
>2 : 2
>'a' : "a"
flat2([1, ['a']]); // Error
>flat2([1, ['a']]) : string[]
>flat2 : <T>(a: (T | (T | T[])[])[]) => T[]
>[1, ['a']] : (number | string[])[]
>1 : 1
>['a'] : string[]
>'a' : "a"
type T10 = T10[];
>T10 : T10
type T11 = readonly T11[];
>T11 : T11
type T12 = (T12)[];
>T12 : T12
type T13 = T13[] | string;
>T13 : T13
type T14 = T14[] & { x: string };
>T14 : T14
>x : string
type T15<X> = X extends string ? T15<X>[] : never;
>T15 : T15<X>
type ValueOrArray1<T> = T | ValueOrArray1<T>[];
>ValueOrArray1 : ValueOrArray1<T>
type ValueOrArray2<T> = T | ValueOrArray2<T>[];
>ValueOrArray2 : ValueOrArray2<T>
declare function foo1<T>(a: ValueOrArray1<T>): T;
>foo1 : <T>(a: ValueOrArray1<T>) => T
>a : ValueOrArray1<T>
declare let ra1: ValueOrArray2<string>;
>ra1 : ValueOrArray2<string>
let x1 = foo1(ra1); // Boom!
>x1 : string
>foo1(ra1) : string
>foo1 : <T>(a: ValueOrArray1<T>) => T
>ra1 : ValueOrArray2<string>
type NumberOrArray1<T> = T | ValueOrArray1<T>[];
>NumberOrArray1 : NumberOrArray1<T>
type NumberOrArray2<T> = T | ValueOrArray2<T>[];
>NumberOrArray2 : NumberOrArray2<T>
declare function foo2<T>(a: ValueOrArray1<T>): T;
>foo2 : <T>(a: ValueOrArray1<T>) => T
>a : ValueOrArray1<T>
declare let ra2: ValueOrArray2<string>;
>ra2 : ValueOrArray2<string>
let x2 = foo2(ra2); // Boom!
>x2 : string
>foo2(ra2) : string
>foo2 : <T>(a: ValueOrArray1<T>) => T
>ra2 : ValueOrArray2<string>
// Repro from #33617 (errors are expected)
type Tree = [HTMLHeadingElement, Tree][];
>Tree : Tree
function parse(node: Tree, index: number[] = []): HTMLUListElement {
>parse : (node: Tree, index?: number[]) => HTMLUListElement
>node : Tree
>index : number[]
>[] : never[]
return html('ul', node.map(([el, children], i) => {
>html('ul', node.map(([el, children], i) => { const idx = [...index, i + 1]; return html('li', [ html('a', { href: `#${el.id}`, rel: 'noopener', 'data-index': idx.join('.') }, el.textContent!), children.length > 0 ? parse(children, idx) : frag() ]); })) : any
>html : any
>'ul' : "ul"
>node.map(([el, children], i) => { const idx = [...index, i + 1]; return html('li', [ html('a', { href: `#${el.id}`, rel: 'noopener', 'data-index': idx.join('.') }, el.textContent!), children.length > 0 ? parse(children, idx) : frag() ]); }) : any[]
>node.map : <U>(callbackfn: (value: [HTMLHeadingElement, Tree], index: number, array: [HTMLHeadingElement, Tree][]) => U, thisArg?: any) => U[]
>node : Tree
>map : <U>(callbackfn: (value: [HTMLHeadingElement, Tree], index: number, array: [HTMLHeadingElement, Tree][]) => U, thisArg?: any) => U[]
>([el, children], i) => { const idx = [...index, i + 1]; return html('li', [ html('a', { href: `#${el.id}`, rel: 'noopener', 'data-index': idx.join('.') }, el.textContent!), children.length > 0 ? parse(children, idx) : frag() ]); } : ([el, children]: [HTMLHeadingElement, Tree], i: number) => any
>el : HTMLHeadingElement
>children : Tree
>i : number
const idx = [...index, i + 1];
>idx : number[]
>[...index, i + 1] : number[]
>...index : number
>index : number[]
>i + 1 : number
>i : number
>1 : 1
return html('li', [
>html('li', [ html('a', { href: `#${el.id}`, rel: 'noopener', 'data-index': idx.join('.') }, el.textContent!), children.length > 0 ? parse(children, idx) : frag() ]) : any
>html : any
>'li' : "li"
>[ html('a', { href: `#${el.id}`, rel: 'noopener', 'data-index': idx.join('.') }, el.textContent!), children.length > 0 ? parse(children, idx) : frag() ] : any[]
html('a', { href: `#${el.id}`, rel: 'noopener', 'data-index': idx.join('.') }, el.textContent!),
>html('a', { href: `#${el.id}`, rel: 'noopener', 'data-index': idx.join('.') }, el.textContent!) : any
>html : any
>'a' : "a"
>{ href: `#${el.id}`, rel: 'noopener', 'data-index': idx.join('.') } : { href: string; rel: string; 'data-index': string; }
>href : string
>`#${el.id}` : string
>el.id : string
>el : HTMLHeadingElement
>id : string
>rel : string
>'noopener' : "noopener"
>'data-index' : string
>idx.join('.') : string
>idx.join : (separator?: string | undefined) => string
>idx : number[]
>join : (separator?: string | undefined) => string
>'.' : "."
>el.textContent! : string
>el.textContent : string | null
>el : HTMLHeadingElement
>textContent : string | null
children.length > 0 ? parse(children, idx) : frag()
>children.length > 0 ? parse(children, idx) : frag() : any
>children.length > 0 : boolean
>children.length : number
>children : Tree
>length : number
>0 : 0
>parse(children, idx) : HTMLUListElement
>parse : (node: Tree, index?: number[]) => HTMLUListElement
>children : Tree
>idx : number[]
>frag() : any
>frag : any
]);
}));
}
function cons(hs: HTMLHeadingElement[]): Tree {
>cons : (hs: HTMLHeadingElement[]) => Tree
>hs : HTMLHeadingElement[]
return hs
>hs .reduce<HTMLHeadingElement[][]>((hss, h) => { const hs = hss.pop()!; return hs.length === 0 || level(h) > level(hs[0]) ? concat(hss, [concat(hs, [h])]) : concat(hss, [hs, [h]]); }, [[]]) .reduce<Tree>((node, hs) => hs.length === 0 ? node : concat<Tree[number]>(node, [[hs.shift()!, cons(hs)]]) , []) : Tree
>hs .reduce<HTMLHeadingElement[][]>((hss, h) => { const hs = hss.pop()!; return hs.length === 0 || level(h) > level(hs[0]) ? concat(hss, [concat(hs, [h])]) : concat(hss, [hs, [h]]); }, [[]]) .reduce : { (callbackfn: (previousValue: HTMLHeadingElement[], currentValue: HTMLHeadingElement[], currentIndex: number, array: HTMLHeadingElement[][]) => HTMLHeadingElement[]): HTMLHeadingElement[]; (callbackfn: (previousValue: HTMLHeadingElement[], currentValue: HTMLHeadingElement[], currentIndex: number, array: HTMLHeadingElement[][]) => HTMLHeadingElement[], initialValue: HTMLHeadingElement[]): HTMLHeadingElement[]; <U>(callbackfn: (previousValue: U, currentValue: HTMLHeadingElement[], currentIndex: number, array: HTMLHeadingElement[][]) => U, initialValue: U): U; }
>hs .reduce<HTMLHeadingElement[][]>((hss, h) => { const hs = hss.pop()!; return hs.length === 0 || level(h) > level(hs[0]) ? concat(hss, [concat(hs, [h])]) : concat(hss, [hs, [h]]); }, [[]]) : HTMLHeadingElement[][]
>hs .reduce : { (callbackfn: (previousValue: HTMLHeadingElement, currentValue: HTMLHeadingElement, currentIndex: number, array: HTMLHeadingElement[]) => HTMLHeadingElement): HTMLHeadingElement; (callbackfn: (previousValue: HTMLHeadingElement, currentValue: HTMLHeadingElement, currentIndex: number, array: HTMLHeadingElement[]) => HTMLHeadingElement, initialValue: HTMLHeadingElement): HTMLHeadingElement; <U>(callbackfn: (previousValue: U, currentValue: HTMLHeadingElement, currentIndex: number, array: HTMLHeadingElement[]) => U, initialValue: U): U; }
>hs : HTMLHeadingElement[]
.reduce<HTMLHeadingElement[][]>((hss, h) => {
>reduce : { (callbackfn: (previousValue: HTMLHeadingElement, currentValue: HTMLHeadingElement, currentIndex: number, array: HTMLHeadingElement[]) => HTMLHeadingElement): HTMLHeadingElement; (callbackfn: (previousValue: HTMLHeadingElement, currentValue: HTMLHeadingElement, currentIndex: number, array: HTMLHeadingElement[]) => HTMLHeadingElement, initialValue: HTMLHeadingElement): HTMLHeadingElement; <U>(callbackfn: (previousValue: U, currentValue: HTMLHeadingElement, currentIndex: number, array: HTMLHeadingElement[]) => U, initialValue: U): U; }
>(hss, h) => { const hs = hss.pop()!; return hs.length === 0 || level(h) > level(hs[0]) ? concat(hss, [concat(hs, [h])]) : concat(hss, [hs, [h]]); } : (hss: HTMLHeadingElement[][], h: HTMLHeadingElement) => any
>hss : HTMLHeadingElement[][]
>h : HTMLHeadingElement
const hs = hss.pop()!;
>hs : HTMLHeadingElement[]
>hss.pop()! : HTMLHeadingElement[]
>hss.pop() : HTMLHeadingElement[] | undefined
>hss.pop : () => HTMLHeadingElement[] | undefined
>hss : HTMLHeadingElement[][]
>pop : () => HTMLHeadingElement[] | undefined
return hs.length === 0 || level(h) > level(hs[0])
>hs.length === 0 || level(h) > level(hs[0]) ? concat(hss, [concat(hs, [h])]) : concat(hss, [hs, [h]]) : any
>hs.length === 0 || level(h) > level(hs[0]) : boolean
>hs.length === 0 : boolean
>hs.length : number
>hs : HTMLHeadingElement[]
>length : number
>0 : 0
>level(h) > level(hs[0]) : boolean
>level(h) : number
>level : (h: HTMLHeadingElement) => number
>h : HTMLHeadingElement
>level(hs[0]) : number
>level : (h: HTMLHeadingElement) => number
>hs[0] : HTMLHeadingElement
>hs : HTMLHeadingElement[]
>0 : 0
? concat(hss, [concat(hs, [h])])
>concat(hss, [concat(hs, [h])]) : any
>concat : any
>hss : HTMLHeadingElement[][]
>[concat(hs, [h])] : any[]
>concat(hs, [h]) : any
>concat : any
>hs : HTMLHeadingElement[]
>[h] : HTMLHeadingElement[]
>h : HTMLHeadingElement
: concat(hss, [hs, [h]]);
>concat(hss, [hs, [h]]) : any
>concat : any
>hss : HTMLHeadingElement[][]
>[hs, [h]] : HTMLHeadingElement[][]
>hs : HTMLHeadingElement[]
>[h] : HTMLHeadingElement[]
>h : HTMLHeadingElement
}, [[]])
>[[]] : never[][]
>[] : never[]
.reduce<Tree>((node, hs) =>
>reduce : { (callbackfn: (previousValue: HTMLHeadingElement[], currentValue: HTMLHeadingElement[], currentIndex: number, array: HTMLHeadingElement[][]) => HTMLHeadingElement[]): HTMLHeadingElement[]; (callbackfn: (previousValue: HTMLHeadingElement[], currentValue: HTMLHeadingElement[], currentIndex: number, array: HTMLHeadingElement[][]) => HTMLHeadingElement[], initialValue: HTMLHeadingElement[]): HTMLHeadingElement[]; <U>(callbackfn: (previousValue: U, currentValue: HTMLHeadingElement[], currentIndex: number, array: HTMLHeadingElement[][]) => U, initialValue: U): U; }
>(node, hs) => hs.length === 0 ? node : concat<Tree[number]>(node, [[hs.shift()!, cons(hs)]]) : (node: Tree, hs: HTMLHeadingElement[]) => any
>node : Tree
>hs : HTMLHeadingElement[]
hs.length === 0
>hs.length === 0 ? node : concat<Tree[number]>(node, [[hs.shift()!, cons(hs)]]) : any
>hs.length === 0 : boolean
>hs.length : number
>hs : HTMLHeadingElement[]
>length : number
>0 : 0
? node
>node : Tree
: concat<Tree[number]>(node, [[hs.shift()!, cons(hs)]])
>concat<Tree[number]>(node, [[hs.shift()!, cons(hs)]]) : any
>concat : any
>node : Tree
>[[hs.shift()!, cons(hs)]] : (HTMLHeadingElement | Tree)[][]
>[hs.shift()!, cons(hs)] : (HTMLHeadingElement | Tree)[]
>hs.shift()! : HTMLHeadingElement
>hs.shift() : HTMLHeadingElement | undefined
>hs.shift : () => HTMLHeadingElement | undefined
>hs : HTMLHeadingElement[]
>shift : () => HTMLHeadingElement | undefined
>cons(hs) : Tree
>cons : (hs: HTMLHeadingElement[]) => Tree
>hs : HTMLHeadingElement[]
, []);
>[] : never[]
}
function level(h: HTMLHeadingElement): number {
>level : (h: HTMLHeadingElement) => number
>h : HTMLHeadingElement
assert(isFinite(+h.tagName[1]));
>assert(isFinite(+h.tagName[1])) : any
>assert : any
>isFinite(+h.tagName[1]) : boolean
>isFinite : (number: number) => boolean
>+h.tagName[1] : number
>h.tagName[1] : string
>h.tagName : string
>h : HTMLHeadingElement
>tagName : string
>1 : 1
return +h.tagName[1];
>+h.tagName[1] : number
>h.tagName[1] : string
>h.tagName : string
>h : HTMLHeadingElement
>tagName : string
>1 : 1
}