function addTlChild(childParams, tl, timePosition, targets, index, length) {
  const isSetter = isNum(childParams.duration) && /** @type {Number} */(childParams.duration) <= minValue;
  // Offset the tl position with -minValue for 0 duration animations or .set() calls in order to align their end value with the defined position
  const adjustedPosition = isSetter ? timePosition - minValue : timePosition;
  tick(tl, adjustedPosition, 1, 1, tickModes.AUTO);
  const tlChild = targets ?
    new JSAnimation(targets,/** @type {AnimationParams} */(childParams), tl, adjustedPosition, false, index, length) :
    new Timer(/** @type {TimerParams} */(childParams), tl, adjustedPosition);
  tlChild.init(1);
  // TODO: Might be better to insert at a position relative to startTime?
  addChild(tl, tlChild);
  forEachChildren(tl, (/** @type {Renderable} */child) => {
    const childTLOffset = child._offset + child._delay;
    const childDur = childTLOffset + child.duration;
    if (childDur > tl.iterationDuration) tl.iterationDuration = childDur;
  });
  tl.duration = getTimelineTotalDuration(tl);
  return tl;
}
@overload
@param  {TimerParams} childParams
@param  {Timeline} tl
@param  {Number} timePosition
@return {Timeline}

@overload
@param  {AnimationParams} childParams
@param  {Timeline} tl
@param  {Number} timePosition
@param  {TargetsParam} targets
@param  {Number} [index]
@param  {Number} [length]
@return {Timeline}

@param  {TimerParams|AnimationParams} childParams
@param  {Timeline} tl
@param  {Number} timePosition
@param  {TargetsParam} [targets]
@param  {Number} [index]
@param  {Number} [length]